PHP AES解密工作加密不

时间:2011-11-18 07:52:16

标签: php iphone ios encryption aes

所以,我有4件作品中的3件,iOS加密 - 解密来自Link 并且我能够解密从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?”

3 个答案:

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

相反,你必须

  • 添加填充(如果加密功能尚未执行此操作),
  • 加密
  • 然后对结果进行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 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。