最近在搞项目中的加解密相关,选了几种方案,最终定下来用RSA+AES进行加解密,在此记录一下,如果有问题,大家可以一起探讨下~
我们项目中的加密流程是:
1.客户端生成AES随机128位秘钥(base64字符串),得到key为aeskey
2.服务端生成两对RSA公私钥,clientPrivate,clientPublick,servePrivate,servePublick
3.客户端使用clientPrivate对明文数据生成数字签名sign
4.将第3步生成的sign作为入参,加入到请求参数中,然后将整体入参转换为json串
5.客户端使用aeskey对json数据进行加密得到密文(encryptData)
6.客户端使用服务端的servePublick公钥对aeskey进行加密,得到密文(encryptKey)
7.分别将encryptData和encryptKey作为参数传输给服务器端
以上为客户端向服务端传输加密数据的过程。
客户端进行解密操作的话,流程反过来即可。
报文封装
- 1.请求端用己方的私钥对原始请求报文进行签名
- 2.组装JSON报文格式如下:
{
"content":原始请求报文,
"sign":签名字符串
}
- 3.请求端生成AES秘钥,并以该秘钥对第2步生成的JSON字符串进行加密(结果为Base64字符串)
- 4.请求端用对方公钥对AES密钥字符串(hexString格式)进行RSA加密(结果为Base64字符串)
- 5.请求端组装JSON报文,格式如下:
{
"package1": 第3步的加密结果,
"package2": 第4步的加密结果
}
解密和验签过程:
- 1.响应端接到请求报文,用己方RSA私钥对报文中的package2字段进行RSA解密,得到AES秘钥字符串
- 2.用1得到的AES秘钥字符串,对请求报文中的package1字段进行解密
- 3.对2解密得到的JSON报文进行解析,content字段为原始报文,sign字段为签名。使用RSA公钥对content和sign进行验签。
秘钥规格:
字符串编码 UTF-8
RSA key长度2048
RSA 加解密时的算法: RSA/ECB/PKCS1Padding
RSA 签名时的算法: SHA256withRSA
AES key长度128位
AES 加解密时的算法: AES/CBC/PKCS5Padding
其中生成128位随机秘钥代码:
- (NSString *)random128BitAESKey {
unsigned char buf[16];
arc4random_buf(buf, sizeof(buf));
NSData *data = [NSData dataWithBytes:buf length:sizeof(buf)];
NSData *base64Data = [data base64EncodedDataWithOptions:0];
NSString * stringBase64 = [[NSString alloc] initWithData:base64Data encoding:0];
return stringBase64;
}