美文网首页程序开发
iOS开发丨AES-128-CBC-NoPadding加密解密算

iOS开发丨AES-128-CBC-NoPadding加密解密算

作者: 炼心术师 | 来源:发表于2019-12-25 15:57 被阅读0次

    上一篇中介绍了iOS实现AES-128-CBC-PKCS7Padding加密解密的方法,实际使用过程中,也许会用到NoPadding的方式,会稍微有些区别,在于不足16位字节的数据需要自己在数据尾部补0x00,解密的时候同样需要去除数据末尾的0x00,下面给出实现方法:

    //加密
    + (NSData *)AES128CBCNoPaddingEncrypt:(NSData *)contentData keyData:(NSData *)keyData ivData:(NSData *)ivData {
        if (!contentData || !keyData || !ivData) {
            return nil;
        }
        void const *keyPtr = keyData.bytes;
        void const *ivPtr = ivData.bytes;
        
        NSUInteger dataLength = [contentData length];
        int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
        NSInteger newSize = 0;
        
        if(diff > 0) {
            newSize = dataLength + diff;
        }
        
        //不足16字节的倍数,则使用0x00自动补齐长度
        char dataPtr[newSize];
        memcpy(dataPtr, [contentData bytes], [contentData length]);
        for(int i = 0; i < diff; i++) {
            dataPtr[i + dataLength] = 0x00;
        }
        
        size_t bufferSize = newSize + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        memset(buffer, 0, bufferSize);
        
        size_t numBytesCrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                              kCCAlgorithmAES,
                                              0x0000,//NoPadding
                                              keyPtr,
                                              kCCKeySizeAES128,
                                              ivPtr,
                                              dataPtr,
                                              sizeof(dataPtr),
                                              buffer,
                                              bufferSize,
                                              &numBytesCrypted);
        
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
        }
        free(buffer);
        return nil;
    }
    
    //解密
    + (NSData *)AES128CBCNoPaddingDecrypt:(NSData *)contentData keyData:(NSData *)keyData ivData:(NSData *)ivData {
        if (!contentData || !keyData || !ivData) {
            return nil;
        }
        void const *keyPtr = keyData.bytes;
        void const *ivPtr = ivData.bytes;
        
        NSUInteger dataLength = [contentData length];
        size_t bufferSize = dataLength + kCCBlockSizeAES128;
        void *buffer = malloc(bufferSize);
        
        size_t numBytesCrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              kCCAlgorithmAES,
                                              0x0000,//NoPadding
                                              keyPtr,
                                              kCCBlockSizeAES128,
                                              ivPtr,
                                              [contentData bytes],
                                              dataLength,
                                              buffer,
                                              bufferSize,
                                              &numBytesCrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
            //去除数据尾部的0x00
            Byte *resultBytes = (Byte *)(resultData.bytes);
            NSInteger i = resultData.length - 1;
            NSInteger c = 0;
            for (; i >= 0; i--) {
                if (resultBytes[i] == 0x00) {
                    c++;
                }
                else {
                    break;
                }
            }
            return [NSData dataWithBytes:resultBytes length:resultData.length - c];
        }
        free(buffer);
        return nil;
    }
    

    keyData和ivData需要保证长度为16字节。

    相关文章

      网友评论

        本文标题:iOS开发丨AES-128-CBC-NoPadding加密解密算

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