所以,我有4件作品中的3件,iOS加密 - 解密来自Link 并且我能够解密从iOS加密的数据我在PHP端加密时遇到了问题。 当我做回声加密代码。 PHP打印的内容类似于F>HFl8aR是什么意思?
SALTKEY ='a16byteslongkey!';
解密代码:工作
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)),
base64_decode($text), 'ecb');
$pad_char = ord(substr($result, -1));
return substr($result, 0, strlen($result) - $pad_char);
加密代码:无效
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)),
base64_encode($text), 'ecb');
$pad_char = ord(substr($result, -1));
return substr($result, 0, strlen($result) - $pad_char);
iOS上的结果:Text =“Hello”
加密=“7opqbb7sEVNoXplyQv / X8g ==”
解密(7opqbb7sEVNoXplyQv / X8g ==)=“你好”
PHP上的结果:Text =“7opqbb7sEVNoXplyQv / X8g ==”
解密=“你好”
加密(Hello)=“_〜TPn~p3MF?”
答案 0 :(得分:3)
我认为很明显,IOS加密提供了7位结果(看起来像base64编码),而PHP提供了8位表示。
你似乎没有完成逆转操作。
通过base64_decode
输入执行解密,然后应用mcrypt_decrypt
。因此,要反过来执行此操作,您需要先mcrypt_encrypt
,然后 base64_encode
。
即
$result = base64_encode(
mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
(SALTKEY . str_repeat(chr(0x00), 16)),
$text, 'ecb'));
答案 1 :(得分:2)
您的加密看起来很虚伪:
$result = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)),
base64_encode($text), 'ecb');
$pad_char = ord(substr($result, -1));
return substr($result, 0, strlen($result) - $pad_char);
您使用base64对文本进行编码,然后对其进行加密,然后尝试删除填充?
相反,你必须
这可能是这样的:
$padded = pad($text);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)),
$padded, 'ecb');
$result = base64_encode($encrypted);
(有关如何创建填充的示例,请查看mcrypt_encrypt documentation处的用户提供的说明。)
当然,还有一些事情需要注意:
如果您对密码学一无所知,请不要使用ECB模式。这是一种不安全的操作方式。使用CBC模式(带随机初始化向量,随数据一起发送)。
您可以通过用零填充SALTKEY来创建密钥。这使得您的密钥效果比必要的要弱。 (无论如何,在代码中使用密钥进行硬编码都是一个坏主意。)提供一个完整的128位密钥,或者使用salt和密钥派生函数(如PBKDF-2)从密码中获取一个密钥计数很高的密钥。
您的解密函数还应检查填充是否有效(即由相同的字节组成),而不是简单地删除它。
您还应该在消息中使用消息身份验证代码(MAC),以避免一些允许解密消息的选择密文攻击。
答案 2 :(得分:1)
在此处查看我的帖子:PHP iOS AES Encryption
当我一遍又一遍地看到同样的问题时,我会继续重新发布这个问题。
我刚刚完成了同样的项目。我使用了你在“也考虑过......”中引用的库。
以下是使用php解密的一些示例代码:
$iv2 = '';
for($i=0;$i<16;$i++){
$iv2 .= "\0";
}
$plain_text_CBC = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_text, MCRYPT_MODE_CBC, $iv2);
var_dump($plain_text_CBC);
确保您的密钥都是256位(32个字符,我还没有任何编码问题,但如果您这样做,请记住您正在加密字节,而不是字符)。请注意,MCRYPT_RIJNDAEL_128中的128是块大小而不是密钥大小,而在方法AES256DecryptWithKey中,256是对密钥大小的引用,而块大小是128. AES256DecryptWithKey在CBC模式下运行,但具有空初始化向量( ⅳ)。
CBC意味着每个块都依赖于最后一个块,因此它使用预设的,通常是随机的,“块-1”,称为IV
ECB意味着每个块都以相同的方式加密,因此它揭示了同一消息中的两个块是否相同。提到的图书馆没有使用它,所以我提到它只是为了对比。
使用零iv(0000000000000000,以字节为单位)被认为是不安全的,但它确实为您提供了一些额外的安全性(但是仍然可以判断您的纯文本的前16个字符是否每次都相同)。要解决这个问题,你必须为IV创建一个NSData * iv变量,并修改NSData + AESCrypt.m的CCcrypt参数,为iv参数添加[iv bytes](我还没有测试过这段代码),你会需要存储此iv并将其与您的消息一起传递给php。但首先我会测试并使所有工作都处于零iv。