iOS安全之路--AES

作者: CatchZeng | 来源:发表于2016-05-10 11:38 被阅读1461次

    一、AES简介

    高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法。AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准。根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128、AES-192和AES-256。

    二、算法描述

    AES1
    AES2
    AES算法较为复杂这里不再赘述,如有兴趣可点击描述出处查看更多资料。

    三、算法实现

    @implementation CATSecurity
    
    #pragma mark --
    #pragma mark -- AES
    
    /**
     *  get data's aes256 encrypt data
     *
     *  @param data source data
     *  @param key  key for encrypt/decrypt  !!!key length must be 16
     *
     *  @return aes256 encrypt data
     */
    +(NSData *)aes256EncryptWithData:(NSData *)data key:(NSString *)key{
        if (!key || key.length !=16) {
            NSLog(@"key length must be 16");
            return nil;
        }
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = data.length;
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesEncrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              keyPtr, kCCBlockSizeAES128,
                                              NULL,
                                              data.bytes, dataLength,
                                              buffer, bufferSize,
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        }
        free(buffer);
        return nil;
    }
    
    /**
     *  get source data from aes256 encrypt data
     *
     *  @param data aes256 encrypt data
     *  @param key  key for encrypt/decrypt  !!!key length must be 16
     *
     *  @return source data
     */
    +(NSData *)aes256DecryptWithData:(NSData *)data key:(NSString *)key{
        if (!key || key.length !=16) {
            NSLog(@"key length must be 16");
            return nil;
        }
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        NSUInteger dataLength = data.length;
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              keyPtr, kCCBlockSizeAES128,
                                              NULL,
                                              data.bytes, dataLength,
                                              buffer, bufferSize,
                                              &numBytesDecrypted);
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        }
        free(buffer);
        return nil;
    }
    
    /**
     *  get string's aes256 encrypt data
     *
     *  @param string source string
     *  @param key  key for encrypt/decrypt  !!!key length must be 16
     *
     *  @return aes256 encrypt data
     */
    +(NSData*)aes256EncryptWithString:(NSString*)string key:(NSString *)key{
        if (!key || key.length !=16) {
            NSLog(@"key length must be 16");
            return nil;
        }
        NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
        NSData *encryptedData = [self aes256EncryptWithData:data key:key];
        return encryptedData;
    }
    
    /**
     *  get source string from aes256 encrypt data
     *
     *  @param data aes256 encrypt data
     *  @param key  key for encrypt/decrypt  !!!key length must be 16
     *
     *  @return source string
     */
    +(NSString*)aes256DecryptStringWithData:(NSData *)data key:(NSString *)key{
        if (!key || key.length !=16) {
            NSLog(@"key length must be 16");
            return nil;
        }
        NSData *decryData = [self aes256DecryptWithData:data key:key];
        NSString *string = [[NSString alloc] initWithData:decryData encoding:NSUTF8StringEncoding];
        return string;
    }
    
    @end
    

    四、补充

    由于iOS、java的平台差异,AES的加密算法存在兼容性问题(iOS的AES Padding只支持ccPKCS7Padding, ccNoPadding),为了使用方便,我找了一份可兼容的Java的代码并做了测试,详见工程的java目录。

    相关文章

      网友评论

      • wokenshin:Hi 请问AES128 这个地方为什么生成的是32位的数据呢?不是应该是16位吗?我想生成16位的需要修改对应的参数就可以了吗?
      • objcat:不错 mark
      • 小凡凡520:pic cs7和cs5能否兼容呢

      本文标题:iOS安全之路--AES

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