很多java服务器对3des的加解密支持的是CBC/pkcs5padding方式,但是iOS这边大部分使用的是kCCOptionPKCS7Padding的填充方式,所以要做个对应处理才可行。
注意3des加解密的偏移量一定要和服务端保持一致,如果发现加密数据不一致请检查这个偏移量是否设置正确
- 需要导入的文件是:
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCrypto.h>
3DES 加密方法(工作模式CBC/填充方式pkcs5padding)
/*
3des加密 。秘钥说明:gkey使用24位或者32位字符串
*/
+(NSString *)doEncryptStr:(NSString *)originalStr dKey:(NSString *)gkey qIv:(NSString *)gIv{
//把string 转NSData
NSData* data = [originalStr dataUsingEncoding:NSUTF8StringEncoding];
//length
size_t plainTextBufferSize = [data length];
const void *vplainText = (const void *)[data bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [gkey UTF8String];
//偏移量
const void *vinitVec = (const void *) [gIv UTF8String];
//配置CCCrypt
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES, //3DES
kCCOptionPKCS7Padding, //设置模式//cbc工作模式下,不要设置cbc,填充方式使用kCCOptionPKCS7Padding和pkcs5是一样的。但是位移量gIv需要保持一致
vkey, //key
kCCKeySize3DES,
vinitVec, //偏移量,这里不用,设置为nil;不用的话,必须为nil,不可以为@""
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSString *result = [GTMBase64 stringByEncodingData:myData];
return result;
}
3DES 解密方法(工作模式CBC/填充方式pkcs5padding)
//3des字符串解密
+(NSString*)doDecEncryptStr:(NSString *)encryptStr dKey:(NSString *)gkey qIv:(NSString *)gIv{
NSData *encryptData = [GTMBase64 decodeData:[encryptStr dataUsingEncoding:NSUTF8StringEncoding]];
size_t plainTextBufferSize = [encryptData length];
const void *vplainText = [encryptData bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [gkey UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,//cbc工作模式下,不要设置cbc,填充方式使用kCCOptionPKCS7Padding和pkcs5是一样的。但是位移量gIv需要保持一致
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSString *result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding];
return result;
}