iOS AES/CBC/PKCS7Padding加密、解密问题

作者: 阿聪o | 来源:发表于2016-06-08 15:53 被阅读5433次

先直接贴上源码吧,给NSData添加加密、解密的扩展:

.h文件

#import <Foundation/Foundation.h>

@interface NSData (AES)

//加密
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv;

//解密
- (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv;

@end

.m文件

#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES)

//加密
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv
{
    return [self AES128operation:kCCEncrypt key:key iv:iv];
}

//解密
- (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv
{
    return [self AES128operation:kCCDecrypt key:key iv:iv];
}

- (NSData *)AES128operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
    char keyPtr[kCCKeySizeAES128 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    // IV
    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    size_t bufferSize = [self length] + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    
    
    CCCryptorStatus cryptorStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
                                            keyPtr, kCCKeySizeAES128,
                                            ivPtr,
                                            [self bytes], [self length],
                                            buffer, bufferSize,
                                            &numBytesEncrypted);
    
    if(cryptorStatus == kCCSuccess){
        NSLog(@"Success");
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }else{
        NSLog(@"Error");
    }
    
    free(buffer);
    return nil;
}

@end

使用方法

    NSString *key = @"efrVN9vy6MxuHrtG";
    NSString *iv = @"N3nLasdhgypjZu3r";
    
    NSString *str1 = @"you are not that into me";
    NSData *data1 = [str1 dataUsingEncoding:NSUTF8StringEncoding];
    //加密
    data1 = [data1 AES128EncryptWithKey:key iv:iv];
    //解密
    NSData *data2 = [data1 AES128DecryptWithKey:key iv:iv];
    NSString *str2 = [[NSString alloc] initWithData:data2 encoding:NSUTF8StringEncoding];
    NSLog(@"str2:%@", str2);
    

此处加密跟解密都是在前端进行,运行项目后控制台能正确的打印 “str2:you are not that into me”。但是一般采用的做法是服务器进行加密、前端进行解密。这里加密后的data1是无法转换成字符串的,所以服务器一般会采用base64进行加密生成对应的NSData,然后转成str提供给前端使用,所以前端拿到str后需要转换成NSData,然后进行base64解密,再进行AES解密才能获取正确的数据。详细代码如下:

    //server处理
    //server 会对AES加密后的data1 进行base64加密,然后将str提供给前端处理
    NSData *data3 = [GTMBase64 encodeData:data1];
    NSString *str3 = [[NSString alloc] initWithData:data3 encoding:NSUTF8StringEncoding];
    NSLog(@"str3:%@", str3);
    
    //前端处理
    NSData *data4 = [str3 dataUsingEncoding:NSUTF8StringEncoding];
    data4 = [GTMBase64 decodeData:data4];
    NSData *data5 = [data4 AES128DecryptWithKey:key iv:iv];
    NSString *str4 = [[NSString alloc] initWithData:data5 encoding:NSUTF8StringEncoding];
    NSLog(@"str4:%@", str4);

相关代码github连接

相关文章

网友评论

  • 如晴天似雨天_1013:楼主这句话没理解-- 什么叫加密后的data1是无法转换成字符串的。。nsdata不是可以用base64或者其他形式生成字符串吗
  • 如晴天似雨天_1013:为什么都用GTMBase64而不用系统自带的呢
  • bense100: NSString *iv = @"N3nLasdhgypjZu3r";

    我发现我 改变 这个值 多加密的结果没有影响,是我忽视了什么?
  • 2d93582d4179:iv是什么
  • 白屏:iv是什么东东
  • 冷冷冷香:我司后端是go写的,死活对不上...
    阿聪o:@冷冷冷香 打si他
  • feng_dev:如果后台是 java 写的 java 只支持 PKCS5Padding 的 ,怎么能让 iOS 的 适配 java版本的
    曾先森:确定是兼容的吗?我测试了好像并不兼容啊
    feng_dev:@阿聪o 恩 。我也查到了 是兼容的
    阿聪o:@枫子哥 网上查了,说是兼容的。只是补位不同。没遇到过没实践。:cry:

本文标题:iOS AES/CBC/PKCS7Padding加密、解密问题

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