- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是密码学的新手,我正在构建一些测试应用程序以尝试了解它的基础知识。我不是要从头开始构建算法,而是要让两个不同的 AES-256 实现相互通信。
我有一个数据库,其中填充了 this Javascript implementation存储在 Base64 中。现在,我正在尝试获取一个 Objective-C 方法来解密其内容,但我对实现中的差异有一点迷茫。我能够在 Javascript 中加密/解密,我能够在 Cocoa 中加密/解密,但不能使在 Javascript 中加密的字符串在 Cocoa 中解密,反之亦然。
我猜它与初始化向量、随机数、计数器操作模式或所有这些有关,坦率地说,目前我不了解这些。
这是我在 Objective-C 中使用的内容,主要改编自 this和 this :
@implementation NSString (Crypto)
- (NSString *)encryptAES256:(NSString *)key {
NSData *input = [self dataUsingEncoding: NSUTF8StringEncoding];
NSData *output = [NSString cryptoAES256:input key:key doEncrypt:TRUE];
return [Base64 encode:output];
}
- (NSString *)decryptAES256:(NSString *)key {
NSData *input = [Base64 decode:self];
NSData *output = [NSString cryptoAES256:input key:key doEncrypt:FALSE];
return [[[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding] autorelease];
}
+ (NSData *)cryptoAES256:(NSData *)input key:(NSString *)key doEncrypt:(BOOL)doEncrypt {
// 'key' should be 32 bytes for AES256, will be null-padded otherwise
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [input length];
// See the doc: For block ciphers, the output size will always be less than or
// equal to the input size plus the size of one block.
// That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void* buffer = malloc(bufferSize);
size_t numBytesCrypted = 0;
CCCryptorStatus cryptStatus =
CCCrypt(doEncrypt ? kCCEncrypt : kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionECBMode | kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
nil, // initialization vector (optional)
[input bytes], dataLength, // input
buffer, bufferSize, // output
&numBytesCrypted
);
if (cryptStatus == kCCSuccess) {
// the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesCrypted];
}
free(buffer); // free the buffer;
return nil;
}
@end
当然,输入是事先经过Base64解码的。
我看到在 Javascript 中使用相同 key 和相同内容的每次加密都会给出不同的加密字符串,而 Objective-C 实现却并非如此,它总是给出相同的加密字符串。我已经阅读了 this post 的答案这让我相信我在矢量初始化方面的一些事情是正确的,但我需要你的帮助来查明到底发生了什么。
谢谢!
最佳答案
是的,这两种实现之间存在许多差异。
Javascript实现采用CTR模式,Objective-C实现采用ECB模式(ECB较弱,不宜使用。)
Javascript 实现使用键扩展。 IE。它在将 key 传递给 AES 代码之前对其进行转换。不确定 Objective-C 实现。无论如何,您几乎可以确定这两个实现没有使用相同的 key 进行加密。
Javascript 实现使用当前时间生成一个 8 字节的 IV,该 IV 被添加到密文之前。此 IV 用于初始化 CTR 模式的计数器。由于 IV 的变化,将相同的明文加密两次将导致不同的密文。也可以使用当前时间为 CTR 模式生成 IV,只要您不在同一时钟节拍 () 内加密两个密文即可。 Objective-C 实现不使用 IV(因为它使用 ECB 模式)。
Objective-C 代码使用 PKCS #7 填充,Javascript 代码不使用任何填充。这是使用不同加密模式的结果。
此外,您还必须检查密文是如何编码的。 Javascript 代码使用 Base64 编码。 Objective-C 代码太多分布在几个帖子中,我没有找到相关代码。
关于javascript - 两种 AES 算法之间的互操作性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2529772/
我是一名优秀的程序员,十分优秀!