RSA加密在Android中的使用

2019-12-25  本文已影响0人  TomRidder

1.RSA介绍

RSA是一种常用的非对称加密算法,所谓非对称加密是指使用一对密钥(公钥和私钥)进行加密和解密,公钥人人都可以获得,用于加密数据,私钥保存在服务器中,用于解密数据。

2. 在Android中使用RSA

Java中已内置RSA支持,示例代码如下:

2.1 从字符串加载公钥

    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通过X509编码的Key指令获得公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(android.util.Base64.decode(publicKey.getBytes(), android.util.Base64.URL_SAFE));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

这里是用安卓自带的Base64加密解密。必须注意加密解密的第二个参数必须选成android.util.Base64.URL_SAFE。Default会报错 公钥非法。

2.2 RSA加密数据

    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return android.util.Base64.encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()), android.util.Base64.URL_SAFE);
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
        }
    }
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
        }
        byte[] resultDatas = out.toByteArray();

        try {
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultDatas;
    }

这里注意用于加密时的Cipher,创建的参数不要写成只带”RSA”的:

Cipher cipher = Cipher.getInstance("RSA");

应为这种的

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");

最后不要忘了将参数用Base64编码

param = URLEncoder.encode((String)param,"utf-8");

3.发送数据到后台

最后只需要讲用户名和加密的密码通过okhttp传到后台即可。

上一篇下一篇

猜你喜欢

热点阅读