Android使用非对称加密RSA提高数据安全性
RSA算法1978年出现,是第一个既能用于数据加密也能用于数字签名的算法,易于理解和操作。发明者:Ron Rivest, Adi Shamir 和 Leonard Adleman。早在1973年,英国国家通信总局的数学家Clifford Cocks就发现类似的算法,但其发现被列为绝密,直到1998年才公诸于世。
RSA是一种常用的非对称加密算法,所谓非对称加密是指使用一对密钥(公钥和私钥)进行加密和解密,公钥人人都可以获得,用于加密数据,私钥保存在服务器中,用于解密数据。
一. OpenSSL操作RSA相关key:
为了加密,我们首先需要生成加解密所需的一堆公钥和私钥,如果使用OpenSSL在Linux命令行操作下可以方便做到:
生成pkcs1格式的1024位私钥, 可以用于服务端私钥解密:
1
openssl genrsa -out private.pem 1024
pkcs1格式私钥转pkcs8格式私钥:
1
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
从pkcs1私钥中生成pkcs8公钥
1
openssl rsa -in private.pem -pubout -out public.pem
从pkcs8私钥中生成pkcs8公钥
1
openssl rsa -in pkcs8.pem -pubout -out public_pkcs8.pem
可以看到,3和4生成的pkcs8公钥都是一样的,之所以要转pkcs8公钥是因为原生Android只能支持pkcs8格式
二. 公钥在Android设备上使用
我们生成的密钥,实际上是一个文本文件,里面用base64编码描述了实际密钥的二进制字节码,所以我们拿到pkcs8的密钥,首先还要还原字节数组。
去掉密钥文件里的头尾描述:—–BEGIN PUBLIC KEY—– 和 —–END PUBLIC KEY—– ,我们只需要中间的base64编码字符串。
解析Base64,得到最终密钥的的byte数组。(当然这些步骤也可以提前处理好,比如事先就把base64转换成二进制储存在文件中,或者编码在代码中,到时候直接用就可以)
我使用了AndroidUtilCode,解码Base64很方便:1
implementation 'com.blankj:utilcode:1.25.9'
Base64解码
1
byte[] pub = EncodeUtils.base64Decode(pp);
使用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解码后得到密文。