gpt4 book ai didi

javascript - 两种 AES 算法之间的互操作性

转载 作者:行者123 更新时间:2023-11-30 13:40:35 25 4
gpt4 key购买 nike

我是密码学的新手,我正在构建一些测试应用程序以尝试了解它的基础知识。我不是要从头开始构建算法,而是要让两个不同的 AES-256 实现相互通信。

我有一个数据库,其中填充了 this Javascript implementation存储在 Base64 中。现在,我正在尝试获取一个 Objective-C 方法来解密其内容,但我对实现中的差异有一点迷茫。我能够在 Javascript 中加密/解密,我能够在 Cocoa 中加密/解密,但不能使在 Javascript 中加密的字符串在 Cocoa 中解密,反之亦然。

我猜它与初始化向量、随机数、计数器操作模式或所有这些有关,坦率地说,目前我不了解这些。

这是我在 Objective-C 中使用的内容,主要改编自 thisthis :

@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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com