iOS AES 加密,CBC、NoPadding

这几天项目要求做一个加密功能,采用的是 AES 加密,要求是 CBC 方式NoPadding。项目需求只有加密功能,所以这里没有对应的解密方法。不过照着加密的方法推导一下,结合网上的文章看一看,差不多也能写出来。
项目并没有用GTMBase64做转码,大致的流程是:

加密内容----转成 NSData ---- AES 加密并得到结果 ---- 把结果转成16进制传给后台 ---- 完事儿

首先需要的参数:
  • key:移动端和后端约定的秘钥。
  • ivValue:可选的初始化向量,我这方法里就没用到这个值。
  • content:就是你需要加密的内容。
接下来是加密部分:

导入头文件#import
代码

+ (NSString *)AES128Encrypt:(NSData *)plainText keyString:(NSString *)keyStr
{
    //  这里的 plainText 是由需要加密的内容 string 转成 NSData 的,下面会详细说.
    NSUInteger dataLength = [plainText length];
    
    unsigned long diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
    unsigned long newSize = 0;
    
    if(diff > 0)
    {
        newSize = dataLength + diff;
    }
    
    char dataPtr[newSize];
    memcpy(dataPtr, [plainText bytes], [plainText length]);
    for(int i = 0; i < diff; i++)
    {
        //  0x0000 代表 no padding 
        dataPtr[i + dataLength] = 0x0000;
    }
    
    size_t bufferSize = newSize + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    memset(buffer, 0, bufferSize);
    
    size_t numBytesCrypted = 0;
    
    //    这里的 byte 表示初始化向量,下面会详细说.
    //    Byte byte[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          0x0000,                 //  0x00 表示 no padding,其他的根据情况来选
                                          [keyStr UTF8String],    //  keyPtr
                                          kCCKeySizeAES128,
                                          NULL,                   //  原本是初始化向量值,不过是可选的,所以用 NULL
                                          dataPtr,
                                          sizeof(dataPtr),
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        //    将加密好的数据转成16进制的字符
        return [self hexStringFromData:resultData];
    }
    free(buffer);
    return nil;
}


+ (NSString *)hexStringFromData:(NSData *)data {
    Byte *bytes = (Byte *)[data bytes];
    // 下面是Byte 转换为16进制。
    NSString *hexStr = @"";
    for(int i=0; i<[data length]; i++) {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i] & 0xff]; //16进制数
        newHexStr = [newHexStr uppercaseString];
        
        if([newHexStr length] == 1) {
            newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
        }
        
        hexStr = [hexStr stringByAppendingString:newHexStr];
        
    }
    return hexStr;
}
说明
  • 这里说说上面代码里提到的 plainText。
    项目里要求先把 content 转成 data,如果 data 的长度不足64位需要在末尾补0。所以原本是 string 类型的 plainText 在这儿就是 data 类型了,可以根据自己的需要改一下子就行。把代码放在下面,有需要的就用,没需要的就略过吧。
  • 还有一个初始化向量,刚开始后台给了这个值,就是代码里那16个0x00的 byte 数组。但是后来发现这个向量值用不上,所以本文一开头儿也说了这玩意儿可选,看具体情况来吧。
  • 最后把加密完的内容转成16进制也是项目需求,具体转不转不强求,只要后台能解密出来就行。
    NSString *contStr = @"这是一个天大的秘密内容";
    //  把内容转成 data
    NSData *contData = [contStr dataUsingEncoding:NSUTF8StringEncoding];
    //  创建一个64位的 byte 数组
    //Byte *byteData = (Byte*)malloc(64);     //  这样创建的数组在位数不够时好像并不会补0
    Byte byteData[64] = {0};
    //  得到转化成 data 的内容的 byte 数组
    char *byteObj = (char *)[contData bytes];
    //  把内容的 byte 遍历到新的 byte 数组里去
    for (int i=0; i
最后

不明白的地方,如果哪位明白人儿能搞懂,麻烦你给翻译翻译,谢谢了!
当然了,自己也得找找帖子琢磨琢磨,以下是参考过的帖子。

iOS AES128 CBC No Padding加密解密
AES加密 - iOS与Java的同步实现
[拿走直接用] iOS加密:AES+Base64

你可能感兴趣的:(iOS AES 加密,CBC、NoPadding)