iOS开发-AES、DES加密

作者: 海0_0滨 | 来源:发表于2017-03-31 17:38 被阅读465次

本文主要说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常用加解密方式

    AES128 AES128加密 AES128解密 3DES 3DES加密 3DES解密 DES DES加密 DES解密

  • Java AES/DES加密&解密

    DES DES加密&解密代码如下: AES AES加密&解密代码如下:

  • iOS开发-AES、DES加密

    本文主要说AES加密,而DES大同小异,揭秘也是一个属性的问题首先,网络上关于iOSAES加密的资料与方法有很多,...

  • android 3DES加密和MD5加密

    经常使用加密算法:DES、3DES、RC4、AES,RSA等;对称加密:des,3des,aes非对称加密:rsa...

  • Android 加密解密的几种方式总结

    经常使用加密算法:DES、3DES、RC4、AES,RSA等; 对称加密:des,3des,aes 非对称加密:r...

  • iOS常用加密算法

    本篇主要介绍笔者在iOS开发工作中用到的加解密算法的使用,主要包括:1)对称加密算法:AES、DES、3DES2)...

  • iOS 对称加密 DES,3DES,AES128,AES256

    前言 最近开发的功能需要用对网络传输的数据进行加密,因此调研了常用了对称加密DES,3DES,AES128,AES...

  • IOS的签名机制

    前言 了解IOS的数字签名机制之前我们需要掌握以下几个知识:加密解密(对称加密(DES 3DES AES),非对称...

  • 数据加密--学习

    常用加密算法 AES MD5 BASE64 RSA DES 3DES RC4 对称加密 des,3des,aes非...

  • crypto-js实现加密解密

    1、DES加密 2、DES解密 3、AES加密 4、AES解密 5、注意:js的前端加密不能与java加密代码写的...

网友评论

  • 不懂后悔:加密正确。解密出来的结果不对
    海0_0滨:@不懂后悔 你试试这个,好久没看他了,这是我的代码,他好像跟密钥长度也有关系,建议还是去配合在线加密解密多试试。确定好是咱们的问题还是后台的问题。
    /**
    * 解密
    *
    * @param encryptText 密文
    * @param key 密钥
    *
    * @return 明文
    */
    + (NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key {

    char keyPtr[kCCKeySizeAES128 + 1];
    memset(keyPtr, 0, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSData *data = [[NSData alloc] initWithBase64EncodedString:encryptText options:NSDataBase64DecodingIgnoreUnknownCharacters];

    NSUInteger dataLength = [data length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);

    size_t numBytesCrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
    kCCAlgorithmAES128,
    kCCOptionPKCS7Padding|kCCOptionECBMode,
    keyPtr,
    kCCBlockSizeAES128,
    NULL,
    [data bytes],
    dataLength,
    buffer,
    bufferSize,
    &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
    NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
    return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
    }
    free(buffer);
    return nil;
    }
    不懂后悔:@海0_0滨 加密的明文是 admin 密钥是:1111111111111111 ,加密的结果是:bBayCa1tDJGRZBCUhNAhxw== 但是返回来加密的结果解密出来的不是admin了。跟后台确认了其他参数。没问题
    海0_0滨:@不懂后悔 加密解密参数都一样吗?跟后台多沟通一下……我当时是没问题的……你可以先找个在线加密解密的网站自己多检查核对一下
  • 如晴天似雨天_1013:你好~如果传入的key和iv是nsdata类型的数据应该怎么做呢
    海0_0滨:转码吧,我记着即使是字符串不也得转码
  • 天净沙:你这文章的解密呢
    海0_0滨:@天净沙 就把参数改为kCCDecrypt就是揭秘……亲

本文标题:iOS开发-AES、DES加密

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