我尝试使用此类加密NSString
#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
我使用此代码:
//This is MD5 key
NSString *key = @"7046dd94480f28dbf4b2e3cb6fa3864a";
NSData *plainDataEmail = [@"app@cfd.com" dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedDataEmail = [plainDataEmail AES128EncryptedDataWithKey:key];
NSString *encryptedStringEmail = [encryptedDataEmail base64EncodedStringWithOptions:0];
encryptedStringEmail是:
JXf7l5dH3qaYvudxCzE98w==
现在我在this site查看相同的详细信息, 原因是:
gnZZGbRaVtCG8Z8Xf732Cw==
请告诉我Objective-c代码中的问题
答案 0 :(得分:2)
这里有很多事情要发生。在某种程度上,几乎每一步看起来都是错误的。我可以走过去,但整个计划非常不安全。除非您需要专门匹配aesencryption.net,否则我的建议是使用跨平台,安全的格式,如RNCryptor。
简短版本:没有普遍接受的使用AES的方法。您必须准确了解双方如何实施其格式并使其匹配。 aesencryption.net没有解释他们的方法(代码示例似乎不相互匹配或网站工具)。正确使用AES非常困难,因此几乎任何任意选择的方法都会非常不安全。
您有一个不正确的关键假设:使用相同密钥加密的明文应始终生成相同的密文。在安全方案中,这应该永远为真。 (如果您正在使用正确使用的工具,那么您将得到匹配的输出,但这是因为它们不安全的实现。)除了在极少数情况下您需要可重复性并故意牺牲安全性对于它,方案中应该至少有一个随机元素,使每个加密都是唯一的。在上面的代码中,该随机元素应该是IV。您应该生成随机IV并将其传递给加密器。
虽然您期望128位加密,但您的密钥实际上是256位长。您可能认为密钥的第一个字节是0x70,但这不正确。它是0x37,它是&#34; 7&#34;的UTF-8编码。您正在传递一个字符串,它只是UTF-8编码,然后被截断(或填充为零)为16个字节。 (这是ObjC代码如此不安全的关键原因之一。)
目前还不清楚aesencryption.net对密钥做了什么;他们没有显示他们的代码,他们的代码示例也不清楚。他们的Java示例是关键,但我不认为他们的PHP代码可以。网站的行为方式,我不认为它是哈希,但它的行为有点奇怪。长度为33个字符的密钥加密与32个字符完全相同,因此它显然是截断的。但它截断为32字节,而不是16字节,即使对于128位密钥也是如此。所以这很奇怪。
最后,ObjC代码正在使用ECB模式,这几乎是您可以选择用于通用加密的最差模式。有一些非常具体的案例,它们很有用,但这不是其中之一。虽然他们的代码示例使用了ECB,但是aesencryption.net使用的并不明显。
答案 1 :(得分:0)
您的链接无法正常使用。
我过去遇到过类似的问题。我怀疑AES128EncryptedDataWithKey
方法正在使用与您尝试链接的网站不同的方法或编码将您的密钥NSString
转换为二进制文件。