Android使用非对称加密RSA提高数据安全性

RSA算法1978年出现,是第一个既能用于数据加密也能用于数字签名的算法,易于理解和操作。发明者:Ron Rivest, Adi Shamir 和 Leonard Adleman。早在1973年,英国国家通信总局的数学家Clifford Cocks就发现类似的算法,但其发现被列为绝密,直到1998年才公诸于世。

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

一. OpenSSL操作RSA相关key:

为了加密,我们首先需要生成加解密所需的一堆公钥和私钥,如果使用OpenSSL在Linux命令行操作下可以方便做到:

  1. 生成pkcs1格式的1024位私钥, 可以用于服务端私钥解密:

    1
    openssl genrsa -out private.pem 1024
  2. pkcs1格式私钥转pkcs8格式私钥:

    1
    openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
  3. 从pkcs1私钥中生成pkcs8公钥

    1
    openssl rsa -in private.pem -pubout -out public.pem
  4. 从pkcs8私钥中生成pkcs8公钥

    1
    openssl rsa -in pkcs8.pem -pubout -out public_pkcs8.pem

可以看到,3和4生成的pkcs8公钥都是一样的,之所以要转pkcs8公钥是因为原生Android只能支持pkcs8格式

二. 公钥在Android设备上使用

我们生成的密钥,实际上是一个文本文件,里面用base64编码描述了实际密钥的二进制字节码,所以我们拿到pkcs8的密钥,首先还要还原字节数组。

  1. 去掉密钥文件里的头尾描述:—–BEGIN PUBLIC KEY—– 和 —–END PUBLIC KEY—– ,我们只需要中间的base64编码字符串。
  2. 解析Base64,得到最终密钥的的byte数组。(当然这些步骤也可以提前处理好,比如事先就把base64转换成二进制储存在文件中,或者编码在代码中,到时候直接用就可以)
    我使用了AndroidUtilCode,解码Base64很方便:

    1
    implementation 'com.blankj:utilcode:1.25.9'

    Base64解码

    1
    byte[] pub = EncodeUtils.base64Decode(pp);
  3. 使用RSA对二进制进行加密, 使用AndroidUtilCode也很方便。

    1
    2
    3
    4
    5
    // 加密
    byte[] encode = EncryptUtils.encryptRSA(mTestData, pubKey, 1024, "RSA/ECB/PKCS1Padding");

    // 解密
    byte[] decode = EncryptUtils.decryptRSA(encode, privKey, 1024, "RSA/ECB/PKCS1Padding");

三. 实际使用

  • RSA每一次加密和解密只能对与key相同长度的数据进行操作,所以在encryptRSA()中实际上会分组后多次对数据进行操作
  • RSA运算操作的数据类型都是字节数据,所以我们也可以对文件的二进制数据进行操作,也可以操作字符串,
    而加密生成的二进制不便于http网络传输,可以转换成Base64字符串后传输,后端再做Base64解码后得到密文。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器