RSA 算法 + AES 算法在 Android 中结合使用

前言

加密算法在网络应用中越来越广,为了保证网络请求数据的安全,Android 网络请求中也越来越多的加入加密算法,本文主要是记录 RSA 和 AES 算法在 Android 中的应用


正文

一、 概念

1. RSA 算法
  • RSA 是 1977 年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

  • 到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用 RSA 加密的信息实际上是不能被解破的。

  • RSA 算法属于非对称加密算法,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey),公钥加密,私钥解密;私钥加密,公钥解密。

  • 随机生成一对公钥和私钥,客户端拿公钥,服务端拿私钥。

2. AES 算法
  • 该算法为比利时密码学家 Joan Daemen 和 Vincent Rijmen 所设计,结合两位作者的名字,以 Rijndael 为名投稿高级加密标准的甄选流程。

  • 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称 Rijndael 加密法,
    是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES。

  • 每次用的时候随机生成一个秘钥,用完之后销毁

二、 使用流程

1. 客户端和服务端用的 base64 加密类要一致,这个加密类是一个 jar 包,java 中有自带的 Base64 算法类,但是安卓中却没有,如果不统一 jar 包,解析要出错
1
2
javabase64-1.3.1.jar
2. 客户端使用示例代码

操作步骤:

  1. 客户端随机产生 AES 的密钥

  2. 对身份证信息(重要信息)进行 AES 加密

  3. 通过使用 RSA 对 AES 密钥进行公钥加密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class MainActivity extends AppCompatActivity {
//需要加密的重要信息
private String name = "zhangsan";
private String idCard = "4103271991***";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 加密--------------
*/
// AES 产生的随机秘钥
String key = AESUtils.generateKey();
//加密之后的重要信息
String encryptName = AESUtils.encryptData(key, name);
String encryptIdCard = AESUtils.encryptData(key, idCard);
//对 AES 秘钥进行 RSA 加密
String encryptByPublicKey = RSAUtils.encryptByPublicKey(key);
Log.i("RSAAndAES","AES秘钥为::::"+key);
Log.i("RSAAndAES","encryptName为::::"+encryptName);
Log.i("RSAAndAES","encryptIdCard为::::"+encryptIdCard);
Log.i("RSAAndAES","encryptByPublicKey为::::"+encryptByPublicKey);
}
其中,RSA 的秘钥和公钥是提前生成好的,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2Hy8d1jGGVlxNa3FEfeY5x9i5RxgICZvV/GO
ekpyK/FxU+K44ft3EiUKGE12BS74lcO4j/1iIgbXV6CuonULSIzBwC52o7v2gFSW/5k+Mms
82q0OKu82Oosj2qYD+mlbfeCHxgPrdUwSeYxGWh1u/uM6r1hEkv9pKov+jWqyNuwIDAQAB
私钥:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALYfLx3WMYZWXE1rcUR95jnH2LlH
GAgJm9X8Y56SnIr8XFT4rjh+3cSJQoYTXYFLviVw7iP/WIiBtdXoK6idQtIjMHALnaju/aAVJb/
mT4yazzarQ4q7zY6iyPapgP6aVt94IfGA+t1TBJ5jEZaHW7+4zqvWESS/2kqi/6NarI27AgMBAA
ECgYBlbA5gLlWcO2Hh15DXlMluqiW+YKI4b6lyTMDpoTo+iHWe+HKFkdlMxyfd5NDw3U6CKVblg
yE5vAqYmlgd6Z442cKtkiuFaBe6A6P2VHr8YLCVmB6QgRenASO4fCWqi5quEq/IvPhRpshRyuuJ
cDnziMKx03RnEfZQRSbaK9K3cQJBANzxF1GoOdLsUmSaExhJKnirWXPsDbpu6IBmqUZdXQYDDmv
hs0DJw/JQnuv0gm/gv6Qjy/v3fNHUFcPsQh0undMCQQDTBS6QjYU/2LKQ/RFoTTxLKrcPg3o66B
794jXR+kqLXJDO/UD88EMHHfOWo/QWVZvgdzQCGBErXk+rb41a8hd5AkEAxblUnxUnumUXT0S7d
e50fc0Knr1Pg9qhY9d8AaaoCytNCqrPmll2bDJOJueIm8rMdn46nOFc6QMd/1o9yJPhVQJAVWGS
XrC0SooObjXHFlGx5KQK378N9Mm4yHb/2c8Q3GR+vxGfevhn1nha+AesmmDXKjJxG6vLPqXxTGd
dZX/w2QJBAM5jrVojC5mXQnA1eKzzRSCeAx97vzZX8wZpwqKVHmazd2kayUjzSARkm+P76+sB0G
96kGQJCRm7jEdl5jh5o2s=
私钥的长度要比公钥长的多
Log 打印出来的结果大概是这样:
1
2
3
4
5
6
AES秘钥为::::ecf82772a1ab4282
encryptName为::::9ZaVuJNAKKwOpm7o+k0Tsg==
encryptIdCard为::::DZ970wYy78lxpGfl0m3ziQ==
encryptByPublicKey为::::iLAfMtFq23q+9AIp02KTO9KKq1kmeaN9E41evXJ7UZY7/c4FC2o1
SadDZeB/EA6C9yurGI0X9HQhxtJC5JXwyEU2OVRqIx75a/ILaYyJ+AiJb06F/L/xfIS7nZBnb04d
Y65Bvbg1imr6SESKPuQOX5mJdgpbJZ0Vp2lj0ZGylbw=
3. 服务端使用代码示例

操作步骤:

  1. 对加密后的 AES 密钥进行 RSA 私钥解密,拿到密钥原文;

  2. 对加密后的重要信息进行 AES 解密,拿到原始内容

1
2
3
4
5
6
// 通过 RSA 私钥 还原 AES 秘钥
String AESKEY = RSAUtils.decryptByPrivateKey(encryptByPublicKey);
//通过 AES 秘钥 还原数据
String name1 = AESUtils.decryptData(AESKEY, encryptName);
String idCard1 = AESUtils.decryptData(AESKEY, encryptIdCard);

三、 为什么要两种算法配合使用

  • 上边的例子大概是:客户端加密向服务端请求数据,服务端解密的过程。

  • 而这种过程完全用 RSA 加密也能做到,两种算法结合的原因就是:AES 加密算法的解密速度要比 RSA 快得多,大概100倍。

  • 还有一个原因:两种算法,多个秘钥,更加有利于信息安全。

四、 第三方链接