AES128加密解密方法

AES128加密解密方法

AES介绍

AES(高级加密标准Advanced Encryption Standard)
2000年10月,NIST(美国国家标准和技术协会)宣布通过从15种侯选算法中选出的一项新的密匙加密标准。新的标准将会代替密匙长度变的太短的旧的DES算法。Rijndael被选中成为将来的AES。Rijndael这个名字是从它的两个发明者Rijmen和Daemen的名字得来的。

这个加密体系据说是一种分组加密方法,因为信息的内容是以128位长度的分组为加密单元的。加密密匙长度有128,192或256位多种选择。正象你所知的那样,DES加密的分组长度是64比特,而密匙长度只有64比特。三重DES加密的分组长度通常是64比特,而密匙长度上112比特。

图一描述了AES的操作模式。首先密匙K0和待加密信息按位相与。然后所有要加密的分组都用一个函数F进行迭代计算,计算用的子密匙是由一个密匙扩展函数产生的,初始的密匙是主密匙。

对于AES 函数F要迭代10次。
图2描述的是加密过程中函数F是如何被迭代的。一个128位的分组转换成16个字节,作为下面处理的输入。首先,每一个字节分别经过替换函数S的处理,然后,用第二个置换函数P对16个字节进行处理。然后这个结果就和匙扩展函数产生的子匙进行位与。
匙Ki是用匙扩展函数从第K(i-1)轮的子匙和第K0的密匙得到的。图三描述了匙扩展函数。16个字节的被分成4组,每组4个字节,来进行处理。最后的一组的4个字节由替换函数S(这个S和用F函数进行迭代处理时的S是一样的)来进行替换处理。最初的4个字节的结果和α系数相加,这个系数是与轮数相关的,它是预先定义的。最后,为了得到Ki,把得到的4个字节的结果和K(i-1)匙的最初4个字节按位相加,然后得到的结果又和K(i-1)匙的下面的4个字节按位相加,如此类推。

好了,现在我们简单地看看替换函数是怎么得到的,然后看看ai 常数有什么作用。为了简单的理由,一个字节应该是256个元素集(称为有限域)的一个元素,对于这些元素只包含一些简单的操作(例如加法,乘法,反转)。事实上,前面提到的替换函数S在那个有限域里的反转。置换函数S被定义为一个很简单的操作,以便能简单的实现。ai 系数是和指数I(有限域的元素)成正比的。这些考虑,使得AES实现起来非常有效。

因为AES仅仅在基于简单的位操作运算,这有两个主要的优点:

即使是纯粹的软件实现,AES也是很快的。例如,用C++在奔腾200的电脑上实现的AES的加密速度可达到70M位/秒;
AES并不依赖于S-Box的选择(根据NSA, DES里的S-Boxes可能包含后门),对分析算法抗击差分密码分析及线性密码分析具有能力。

IOS平台下的AES128加密解密

  • 首先导入GTMBase64.h这个头文件,这个头文件在github上有托管,链接为https://github.com/stephenzl/GTBase64
  • 把这个文件加入你的项目,然后再导CommonCrypto/CommonCrypto.h这个系统的头文件
  • 紧接着要定义一个宏,这个宏就是密码,解密加密的密码,密码可自行定义
    define gkey @”xxxxxxxxxxxxxxx”

加密类方法

+(NSString *)AES128Encrypt:(NSString *)plainText
{
 char keyPtr[kCCKeySizeAES128+1];
memset(keyPtr, 0, sizeof(keyPtr));
[gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

char ivPtr[kCCBlockSizeAES128+1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];

int diff = kCCKeySizeAES128 - (dataLength % kCCKeySizeAES128);
int newSize = 0;

if(diff > 0)
{
    newSize = dataLength + diff;
}

char dataPtr[newSize];
memcpy(dataPtr, [data bytes], [data 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,
                                      kCCAlgorithmAES128,
                                      0x0000,               //No padding
                                      keyPtr,
                                      kCCKeySizeAES128,
                                      ivPtr,
                                      dataPtr,
                                      sizeof(dataPtr),
                                      buffer,
                                      bufferSize,
                                      &numBytesCrypted);

if (cryptStatus == kCCSuccess) {
    NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
    return [GTMBase64 stringByEncodingData:resultData];
}
free(buffer);
return nil;

}

解密类方法

+(NSString *)AES128Decrypt:(NSString *)encryptText
{
char keyPtr[kCCKeySizeAES128 + 1];
memset(keyPtr, 0, sizeof(keyPtr));
[gkey getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

char ivPtr[kCCBlockSizeAES128 + 1];
memset(ivPtr, 0, sizeof(ivPtr));
[gIv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];

NSData *data = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
NSUInteger dataLength = [data length];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);

size_t numBytesCrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                      kCCAlgorithmAES128,
                                      0x0000,
                                      keyPtr,
                                      kCCBlockSizeAES128,
                                      ivPtr,
                                      [data bytes],
                                      dataLength,
                                      buffer,
                                      bufferSize,
                                      &numBytesCrypted);
if (cryptStatus == kCCSuccess) {
    NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
    return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];

}


free(buffer);
return nil;

}

你可能感兴趣的:(加密,解密,aes,IOS平台下)