2017-03-15 71 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使用的并不明显。

相关问题