美文网首页iOS开发
iOS使用AES+RSA加密

iOS使用AES+RSA加密

作者: 蜂子fightting | 来源:发表于2018-12-02 21:18 被阅读138次

    由于项目中,登录请求过程中涉及到用户数据的传输,为了用户数据的安全性考虑,决定在请求与相应中使用加密传输的方式。查找了相关资料后发现,目前最广泛的是使用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代码下载

    相关文章

      网友评论

        本文标题:iOS使用AES+RSA加密

        本文链接:https://www.haomeiwen.com/subject/waujcqtx.html