PHP AES解密工作加密不

所以,我有4个工作中的3个,从这个链接 iOS加密解密我能够解密从iOS加密的数据我在PHP端加密时遇到了麻烦。 当我做回声加密代码。 PHP打印类似F>HFl8aR是什么意思?

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~p3MF?”

我认为很明显,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')); 

您的加密看起来很虚伪:

  $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对文本进行编码,然后对其进行加密,然后尝试删除填充?

相反,你必须

  • 添加填充(如果加密function尚未执行此操作),
  • 加密
  • 然后对结果进行base-64编码(如果你想让它以某种方式被人类读取或通过非二进制安全通道传输)。

这看起来像这样:

 $padded = pad($text); $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), $padded, 'ecb'); $result = base64_encode($encrypted); 

(有关如何创建填充的示例,请查看mcrypt_encrypt文档中的用户提供的说明。)

当然,还有一些事情需要注意:

  • 如果您对密码学一无所知,请不要使用ECB模式。 这是一种不安全的操作方式。 使用CBC模式(带随机初始化向量,随数据一起发送)。

  • 您可以通过用零填充SALTKEY来创建密钥。 这使得您的密钥效果比必要的要弱。 (在代码中使用密钥进行硬编码无论如何都是一个坏主意。)提供一个完整的128位密钥,或者使用salt和密钥派生函数(如PBKDF-2)从密码中导出一个密钥计数很高的密钥。

  • 您的解密函数还应检查填充是否有效(即由相同的字节组成),而不是简单地删除它。

  • 您还应该在消息中使用消息身份validation代码(MAC),以避免某些允许解密消息的选择密文攻击。

在这里看到我的post: PHP iOS AES加密

我一直在重复这个问题,因为我一遍又一遍地看到同样的问题。


我刚刚完成了同样的项目。 我使用了你在“也考虑过……”中引用的库。

这是一些用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。