天天看點

iOS中AES192 CBC PKCS7Padding 解碼

1.什麼是AES?

AES(Advanced Encryption Standard,AES)進階加密标準,是美國聯邦政府采用的一種區塊加密标準。這個标準用來替換原來的DES,該算法為比利時密碼學家Joan Daemen和Vincent Rijmen所設計,是以又稱進階加密标準Rijndael加密法。

2.什麼是AES128,AES192,AES256?

AES采用的是對稱加密,密鑰長度支援128位,192位,256位,也即AES128密鑰長度為128/8=16,AES192密鑰長度為192/8=24,AES256密鑰長度為256/8=32。

3.什麼是ECB,CBC加密模式?

ECB(Electronic Code Book電子密碼本)模式,是将加密的資料分成若幹組,每組的長度和密鑰長度相等,每組都用相同的密鑰進行加密,各個組可以進行并行加密。 CBC(Cipher Block Chaining,加密塊鍊)模式,是一種循環模式,前一個分組的密文和目前分組的明文異或操作後再加密,增強了密文被破解的難度。CBC模式涉及兩個東西,一個是密鑰,一個密鑰偏移量,具體可以參考後面的例子。

4.什麼是PKCS5Padding,PKCS7Padding?

PKCS5Padding和PKCS7Padding都是密鑰的一種填充方式,即當密鑰長度不足時的一種密鑰填充方式。PKCS5Padding的填充方式為當密鑰長度不足時,缺幾位補幾個0,eg.針對AES128,如果密鑰為“1234567890”一共10位,缺6位,采用PKCS5Padding方式填充之後的密鑰為“1234567890000000”,補了6個0.PKCS7Padding的填充方式為當密鑰長度不足時,缺幾位補幾個幾,eg.對于AES128,如果密鑰為”1234567890”一共10位,缺6位,采用PKCS7Padding方式填充之後的密鑰為“1234567890666666”。

下面給出一個iOS上AES192采用CBC,PKCS7Padding的解密算法:

+ (NSData *)decryptData:(NSData *)rawData aes256DecryptKey:(NSString *)key   //解密

{

    //密鑰長度加1

    char keyPtr[kCCKeySizeAES192+1];

    //AES iv向量必須先Base64 decode一下,和背景保持一緻(實際使用中要看背景如何處理)

    NSData *ivDecodedData = [[NSData alloc] initWithBase64EncodedString:ELIMPlayBackAESIV options:1];

    bzero(keyPtr, sizeof(keyPtr));

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [rawData length];

    size_t bufferSize = dataLength + kCCBlockSizeAES128;

    void *buffer = malloc(bufferSize);

    size_t numBytesDecrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,

                                          kCCOptionPKCS7Padding,

                                          keyPtr, strlen(keyPtr),

                                          [ivDecodedData bytes],

                                          [rawData bytes], dataLength,

                                          buffer, bufferSize,

                                          &numBytesDecrypted

                                          );

    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

    }

    free(buffer);

    return nil;

}