iOS开发-AES、DES加密

本文主要说AES加密,而DES大同小异,揭秘也是一个属性的问题
首先,网络上关于iOSAES加密的资料与方法有很多,并且也都可以运行,但是大部分作者都是就自己项目写的代码,具体参数和可能出现坑的地方都没有说明白,也就是说,那些代码可能没有错,但就是不适用于你自己的项目。

特别说明:1. 本文是自己项目中用到后用来记录之用,也为了兴许能帮助到的同胞。如果有说的不对的地方,感谢指正;2. 以下代码是自己学习过程中,通过网络上不同大神们的代码结合所成;3. 以下言论需要斟酌后使用,出错不负责,帮你解决问题也不收礼

先上代码

/**
 *  加密
 *
 *  @param plainText 明文
 *  @param key       密钥
 *  @param iv        向量
 *
 *  @return 密文
 */
+ (NSString *)AES256Encrypt:(NSString *)plainText key:(NSString *)key iv:(NSString *)iv {
    
    char keyPtr[kCCKeySizeAES256+1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    char ivPtr[kCCBlockSizeAES128 + 1];
    memset(ivPtr, 0, sizeof(ivPtr));
    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
    
    size_t bufferSize = [data length] + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          [key length],
                                          ivPtr,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        return [resultData base64EncodedStringWithOptions:0];
    }
    free(buffer);
    return nil;
}

需要注意的地方有几个:

  1. CCCrypt 第一个参数:kCCEncrypt:加密 ;kCCDecrypt:解密
  2. CCCrypt 第二个参数:区分AES加密与DES加密
  3. key(密钥)的长度,char keyPtr[kCCKeySizeAES256+1];需要注意此处后台给你的key的长度,AES的key长度kCCKeySizeAES128 = 16, kCCKeySizeAES192 = 24, kCCKeySizeAES256 = 32,
  4. 向量的长度,char ivPtr[kCCBlockSizeAES128 + 1];一般就是16位,我自己认为没有再多的了
  5. 最后一个非常要注意的点:iOS中填充模式没有[kCCOptionPKCS5Padding][1]模式,而如果后台跟安卓又都是kCCOptionPKCS5Padding的话,那iOS就可以在CCCrypt参数中用kCCOptionPKCS7Padding | kCCOptionECBMode(不写的话默认为CBC模式)来代替。以下纯属个人猜想为什么加了这个东西,结果出来就跟kCCOptionPKCS5Padding的一样:因为IV向量默认是16个0,而kCCOptionPKCS7Padding的填充模式又是不足补0,但是ECB加密模式是不需要向量的,所以在kCCOptionPKCS7Padding的基础上加了kCCOptionECBMode就跟kCCOptionPKCS5Padding的是缺几个字节就补充几个字节的几模式结果一样了
  6. 如果不写kCCOptionECBMode,使用了默认的CBC模式,并且没有固定向量IV的话,每次的加密结果都会是不一样的,因为,CBC时需要向量的,所以每次会生成一个随机的向量,所以每次加密结果都不一样。
  7. 在出现错误时从以下几个方面进行检查
    1. key与IV长度问题
    2. 填充模式问题kCCOptionPKCS5Padding,kCCOptionPKCS7Padding
    3. 很多时候,后台的同事也不明白AES加密的具体情况,他们可能也只是从网络上找了一些方法来加密,所以,不用太指望别人跟你说他们模式等东西。最好的办法就是,给后台一个明文,让他们用他们的模式生成一个秘文,然后确定好KEY与IV之后,在自己的程序中修改参数最终确定是那种模式(当然,如果后台给你,把AES加密的各种模式都跟你说了,最好)

  1. PKCS7Padding跟PKCS5Padding的区别就在于数据填充方式,PKCS7Padding是缺几个字节就补几个字节的0,而PKCS5Padding是缺几个字节就补充几个字节的几,好比缺6个字节,就补充6个字节的6 ↩

你可能感兴趣的:(iOS开发-AES、DES加密)