上一篇中介绍了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字节。
网友评论