2017-03-15 86 views
-3

我嘗試使用這個類Objective-C的AES128加密

#import "NSData+AES.h" 
#import <CommonCrypto/CommonCryptor.h> 

@implementation NSData (AES) 

- (NSData *)AES128EncryptedDataWithKey:(NSString *)key 
{ 
    return [self AES128EncryptedDataWithKey:key iv:nil]; 
} 

- (NSData *)AES128DecryptedDataWithKey:(NSString *)key 
{ 
    return [self AES128DecryptedDataWithKey:key iv:nil]; 
} 

- (NSData *)AES128EncryptedDataWithKey:(NSString *)key iv:(NSString *)iv 
{ 
    return [self AES128Operation:kCCEncrypt key:key iv:iv]; 
} 

- (NSData *)AES128DecryptedDataWithKey:(NSString *)key iv:(NSString *)iv 
{ 
    return [self AES128Operation:kCCDecrypt key:key iv:iv]; 
} 

- (NSData *)AES128Operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv 
{ 
    char keyPtr[kCCKeySizeAES128 + 1]; 
    bzero(keyPtr, sizeof(keyPtr)); 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    char ivPtr[kCCBlockSizeAES128 + 1]; 
    bzero(ivPtr, sizeof(ivPtr)); 
    if (iv) { 
     [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; 
    } 

    NSUInteger dataLength = [self length]; 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(operation, 
              kCCAlgorithmAES128, 
              kCCOptionPKCS7Padding | kCCOptionECBMode, 
              keyPtr, 
              kCCBlockSizeAES128, 
              ivPtr, 
              [self bytes], 
              dataLength, 
              buffer, 
              bufferSize, 
              &numBytesEncrypted); 
    if (cryptStatus == kCCSuccess) { 
     return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 
    free(buffer); 
    return nil; 
} 

@end 

我用這個代碼是加密NSString

//This is MD5 key 
NSString *key = @"7046dd94480f28dbf4b2e3cb6fa3864a"; 

NSData *plainDataEmail = [@"[email protected]" dataUsingEncoding:NSUTF8StringEncoding]; 
NSData *encryptedDataEmail = [plainDataEmail AES128EncryptedDataWithKey:key]; 
NSString *encryptedStringEmail = [encryptedDataEmail base64EncodedStringWithOptions:0]; 

encryptedStringEmail是:

JXf7l5dH3qaYvudxCzE98w== 

現在的我m查看this site, 上的相同細節,原因是:

gnZZGbRaVtCG8Z8Xf732Cw== 

請告訴我什麼是我的Objective-C代碼

+0

我的錯誤,我編輯了鏈接 –

+0

在這種情況下,每次都生成相同的JXf7l5dH3qaYvudxCzE98w ==嗎? –

+0

是的相同結果 –

回答

0

您的鏈接無法正常工作的問題。

我以前遇到過類似的問題。我懷疑AES128EncryptedDataWithKey方法是將您的密鑰(NSString)轉換爲使用與您嘗試鏈接的網站不同的方法或不同編碼的二進制文件。

+0

對不起我的錯誤,我再次編輯了這個問題 –

2

這裏有很多事情要做。幾乎每一步看起來在某種程度上都是錯誤的。我可以走過去,但這整個計劃是非常不安全的。我的建議是,除非您需要專門匹配aesencryption.net,否則將使用跨平臺的安全格式,如RNCryptor

簡版:沒有普遍接受的方式來使用AES。你必須確切地知道雙方如何實現他們的格式並使他們匹配。 aesencryption.net沒有解釋他們的方法(代碼示例似乎不匹配對方或網站工具)。正確使用AES非常困難,所以幾乎任何任意選擇的方法都會非常不安全。

您有一個關鍵假設是不正確的:使用相同密鑰加密的明文應始終生成相同的密文。在一個安全的方案中,這應該是從來沒有爲真。 (如果你使用的是正確使用的工具,那麼你會得到匹配的輸出,但那是因爲它們是不安全的實現。)除非在極少數情況下需要可重複性並故意犧牲它的安全性,否則至少應該有該方案中的一個隨機元素可使每種加密都是唯一的。在上面的代碼中,該隨機元素應該是IV。您應該生成一個隨機IV並將其傳遞給加密器。

當您期待128位加密時,您的密鑰實際上是256位長。您可能認爲密鑰的第一個字節是0x70,但這不正確。它是0x37,這是「7」的UTF-8編碼。你傳遞一個字符串,它只是UTF-8編碼,然後截斷(或零填充)爲16字節。 (這是ObjC代碼如此不安全的主要原因之一)。

目前還不清楚aesencryption.net對密鑰做了什麼,他們不顯示他們的代碼,他們的代碼示例不明確。他們的Java例子突破了關鍵,但我不認爲他們的PHP代碼。網站的行爲方式,我不認爲它是哈希,但它的行爲有點怪異。長33個字符的加密與32個字符完全相同,因此它顯然被截斷。但它截斷爲32個字節,而不是16個字節,即使對於128位密鑰也是如此。所有這些都很奇怪。

最後,ObjC代碼使用的是ECB模式,這是您可以爲通用加密選擇的最差模式。有一些很有用的特殊情況,但這不是其中之一。雖然他們的代碼示例使用ECB,但aesencryption.net使用的並不明顯。