iOS开发

iOS使用AES+RSA加密

2018-12-02  本文已影响138人  蜂子fightting

由于项目中,登录请求过程中涉及到用户数据的传输,为了用户数据的安全性考虑,决定在请求与相应中使用加密传输的方式。查找了相关资料后发现,目前最广泛的是使用AES+RSA组合加密的方式。即采用对称加密与非对称加密相结合的方式,综合了对称加密的高效与非对称加密的安全性,是目前大多数项目采用的方式。其大致的思路如下:
首先使用AES对称加密加密要传输的数据(由于数据可能会比较大,所以如果使用RSA非对称加密的话,就很耗性能,影响用户体验),然后用非对称加密RSA来加密AES加密所使用的密钥key,最后把AES加密后的数据,与RSA加密后的key发给服务器,同理后台也使用此方法来进行数据传输。
下面就针对AES与RSA加密的方式以及项目中遇到的问题做下简单的说明。

首先先看下加密的代码:

// 使用AES128 加密
        //随机生成16位字符串的AES 加密的密钥key
        NSString *key = [SecurityUtil randomlyGenerated16BitString];
        NSLog(@"AES加密的秘钥key=%@",key);
        NSLog(@"disJson = %@",[kutils JsonSerializer:dicJson]);
        NSString *encodeBase64 = aesEncryptString([kutils JsonSerializer:dicJson], key);
        NSLog(@"AES128加密:%@",encodeBase64);
        NSString *decryptedText = aesDecryptString(encodeBase64, key);
        NSLog(@"AES解密后的%@", decryptedText);
        /************************
         RAS 加密  ASE的KEY
         ****************************/
        //给随机KEY 加密
        NSString *encWithPubKey = [SecurityUtil encryptString:key publicKey:RSApublicKey];//RSApublicKey RSA加密的公钥
        NSLog(@"RSA加密后的key:%@",encWithPubKey);
        NSMutableDictionary *encryptJsonDict = [NSMutableDictionary dictionary];
        [encryptJsonDict setValue:encWithPubKey forKey:@"key"];
        [encryptJsonDict setValue:encodeBase64 forKey:@"value"];
        
        dicJson = encryptJsonDict;

解密的代码

NSDictionary *temDic = [kutils JsonDeserializer:dataStr];//json解析
        NSString *key = [temDic valueForKey:@"key"];
        NSString *value = [temDic valueForKey:@"value"];
        //RSA公钥解密服务端传过来的AES加密的key
        if (key == nil) {
            NSLog(@"发送登录请求后传过来的字典其中的key为nil");
        }
        NSString *AES_key = [SecurityUtil decryptString:key?:@"key" publicKey:RSApublicKey];
        //然后使用key 来解密AES加密后的value
        if (AES_key && value) {
            
            NSString *dicString = aesDecryptString(value, AES_key);
            NSLog(@"解密后的dicStrign = %@",dicString);
            dic = [kutils JsonDeserializer:dicString];
            
        } else {
            NSLog(@"AES_key 或则value为nil AES_key = %@ value = %@",AES_key,value);
        }

项目中遇到的问题:

  1. AES加密后的数据服务端无法解析
    原因分析:由于 当时我使用的AES加密,设置了填充方式初始向量,交流后发现我们呢后台使用Java的AES加密,他们说找不到设置这两项的方法(我这里觉得肯定是可以设置),没办法,只好没有设置初始向量以及填充方式设置为kCCOptionECBMode | kCCOptionPKCS7Padding
NSString const *kInitVector = @"";//@"A-16-Byte-String";
size_t const kKeySize = kCCKeySizeAES128;

NSData * cipherOperation(NSData *contentData, NSData *keyData, CCOperation operation) {
    NSUInteger dataLength = contentData.length;
    
    void const *initVectorBytes = [kInitVector dataUsingEncoding:NSUTF8StringEncoding].bytes;
    void const *contentBytes = contentData.bytes;
    void const *keyBytes = keyData.bytes;
    
    size_t operationSize = dataLength + kCCBlockSizeAES128;
    void *operationBytes = malloc(operationSize);
    if (operationBytes == NULL) {
        return nil;
    }
    size_t actualOutSize = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(operation,
                                          kCCAlgorithmAES,
                                          kCCOptionECBMode | kCCOptionPKCS7Padding,
                                          keyBytes,
                                          kKeySize,
                                          initVectorBytes,
                                          contentBytes,
                                          dataLength,
                                          operationBytes,
                                          operationSize,
                                          &actualOutSize);
    
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:operationBytes length:actualOutSize];
    }
    free(operationBytes);
    operationBytes = NULL;
    return nil;
}

关于AES加密参数的说明,这里有更加详细的说明大家可以参考:AES加密

  1. 后台发送过来的AES加密后数据iOS端无法正确解析
    此问题很奇怪,因为在demo测试时候,我的客户端是可以正确解析的,但是当在项目中测试的时候发现解析不了,(测试时用的数据很小)最后交流中发现问题所在,我iOS 上AES生成的随机密钥key是字符串格式的,而后台端Java直接是生成二进制格式的密钥key,两端格式没有统一,最后后代改为使用字符串格式的密钥key后,就可以正常解析了。

说明RSA的公钥我这里采用的Java后台生成的经过base64后的字符串。

ASE+RSA代码下载

上一篇下一篇

猜你喜欢

热点阅读