gpt4 book ai didi

php - 为什么 iPad 上的 AES 加密和 PHP 中的解密失败?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:09:22 25 4
gpt4 key购买 nike

我有一个 iPad 应用程序可以将加密信息传输到基于 PHP 的网站,但我在正确解密此信息时遇到了困难。我使用以下代码进行 PHP 端解密:

//Decryption function

function mc_decrypt($decrypt, $key, $iv)
{
$decoded = base64_decode($decrypt);
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $decoded);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return trim($decrypted);
}

我的 iPad 应用程序中的 Objective-C 代码:

#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES256)

- (NSData *)AES256EncryptWithKey:(NSString *)key {
// '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 = [self 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 numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}

free(buffer); //free the buffer;
return nil;
}

- (NSData *)AES256DecryptWithKey:(NSString *)key {
// '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 = [self 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 numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesDecrypted);

if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}

free(buffer); //free the buffer;
return nil;
}

@end

为什么我在尝试解密在 iPad 上编码并在 PHP 端解密的数据时看到数据损坏?

最佳答案

检查您正在使用的 key 。在 PHP 中,MCRYPT_RIJNDAEL_128 _256 等常量不表示 key 强度,而是表示使用的 block 大小。

要使用 PHP 获得 128 位加密,您需要使用 16 字节长的 key 。对于 256,您需要 32 个字节,依此类推。

你的 PHP 和 C 代码在我看来都是正确的。确保在这两种情况下都正确使用了 key 。

作为另一个想法。看起来你在 C 中使用 PKCS#7 填充。我不相信 PHP 被设计为默认使用该填充。如果没记错的话,我相信 Mcrypt 函数使用空填充。

最后检查您在 PHP 中的初始化向量。我注意到您没有在 C 代码中使用它,这意味着您不应该在 PHP 中接受 $iv 变量。这应该作为 NULL 传递到 mcrypt 函数中(但这是非常不鼓励的)。

您应该做的是在您的 C 代码(数据被加密的地方)中随机化一个 IV,然后将 IV 与加密数据一起发送。您可以检测正在使用的算法的 IV 的大小,并将其从加密数据的前面拆分出来,然后用于填充您的 PHP 方面。这进一步保护了您的加密。

关于php - 为什么 iPad 上的 AES 加密和 PHP 中的解密失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7060392/

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