加解密AES128 CBC NoPadding

加密 AES128 CBC NoPadding

 + (NSString *)AES128Encrypt:(NSString *)plainStr keyString:(NSString *)keyStr{
NSData *plainText = [plainStr dataUsingEncoding:NSUTF8StringEncoding];

//  这里的 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] = 0x20;
}

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,
                                      [IV_SEEDS UTF8String],                   //  原本是初始化向量值,不过是可选的,所以用 NULL
                                      dataPtr,
                                      sizeof(dataPtr),
                                      buffer,
                                      bufferSize,
                                      &numBytesCrypted);

if (cryptStatus == kCCSuccess) {
    NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
    //    将加密好的数据转成16进制的字符
    return [self dataToBase64String:resultData];
}
free(buffer);
return nil;  
 }

将加密好的数据转成16进制的字符

+ (NSString *)dataToBase64String:(NSData *)data
 {
if ([data length] == 0)
    return @"";

char *characters = malloc((([data length] + 2) / 3) * 4);
if (characters == NULL)
    return nil;
NSUInteger length = 0;

NSUInteger i = 0;
while (i < [data length])
{
    char buffer[3] = {0,0,0};
    short bufferLength = 0;
    while (bufferLength < 3 && i < [data length])
        buffer[bufferLength++] = ((char *)[data bytes])[i++];

    //  Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
    characters[length++] = CRDEncodingTable[(buffer[0] & 0xFC) >> 2];
    characters[length++] = CRDEncodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
    if (bufferLength > 1)
        characters[length++] = CRDEncodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
    else characters[length++] = '=';
    if (bufferLength > 2)
        characters[length++] = CRDEncodingTable[buffer[2] & 0x3F];
    else characters[length++] = '=';
        }

      return [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
       }

解密AES128 CBC NoPadding

/** 解密AES128 CBC NoPadding
   decryptStr           要解密参数
   keyData                 解密的key
ivData                     解密向量
*/ 
+ (NSData *)AES128CBCNoPaddingDecrypt:(NSString *)decryptStr keyData:(NSData *)keyData ivData:(NSData *)ivData{

NSData *contentData =[self base64StringToData:decryptStr];

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] == 0x20) {
            c++;
        }
        else {
            break;
        }
    }
    return [NSData dataWithBytes:resultBytes length:resultData.length - c];
}
free(buffer);
return nil;
   }

Str转base64

+ (NSData *)base64StringToData:(NSString *)string
{
if (string == nil)
    return nil;
if ([string length] == 0)
    return [NSData data];

static char *decodingTable = NULL;
if (decodingTable == NULL)
{
    decodingTable = malloc(256);
    if (decodingTable == NULL)
        return nil;
    memset(decodingTable, CHAR_MAX, 256);
    NSUInteger i;
    for (i = 0; i < 64; i++)
        decodingTable[(short)CRDBase64EncodingTable[i]] = i;
}

const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding];
if (characters == NULL)     //  Not an ASCII string!
    return nil;
char *bytes = malloc((([string length] + 3) / 4) * 3);
if (bytes == NULL)
    return nil;
NSUInteger length = 0;

NSUInteger i = 0;
while (YES)
{
    char buffer[4];
    short bufferLength;
    for (bufferLength = 0; bufferLength < 4; i++)
    {
        if (characters[i] == '\0')
            break;
        if (isspace(characters[i]) || characters[i] == '=')
            continue;
        buffer[bufferLength] = decodingTable[(short)characters[i]];
        if (buffer[bufferLength++] == CHAR_MAX)      //  Illegal character!
        {
            free(bytes);
            return nil;
        }
    }

    if (bufferLength == 0)
        break;
    if (bufferLength == 1)      //  At least two characters are needed to produce one byte!
    {
        free(bytes);
        return nil;
    }
    //  Decode the characters in the buffer to bytes.
    bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4);
    if (bufferLength > 2)
        bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2);
    if (bufferLength > 3)
        bytes[length++] = (buffer[2] << 6) | buffer[3];
}
bytes = realloc(bytes, length);
return [NSData dataWithBytesNoCopy:bytes length:length];
}

你可能感兴趣的:(加解密AES128 CBC NoPadding)