PHP AES解密工作加密NOT



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

SALTKEY = 'a16byteslongkey!';

解密码:Working

     $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);

加密码:Not Working

     $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 :文本="Hello"
    加密=" 7opqbb7sEVNoXplyQv/X8g=="
    解密(7opqbb7sEVNoXplyQv/X8g==) = "Hello"

  • PHP: Text =" 7opqbb7sEVNoXplyQv/X8g=="
    解密= "Hello"
    加密(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编码文本,然后加密它,然后然后尝试删除填充?

相反,你必须

  • 添加填充(如果加密功能还没有这样做),
  • 然后对结果进行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)从密码中派生一个密钥。

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

  • 你还应该在你的消息中使用消息验证码(MAC),以避免一些允许解密消息的选择密文攻击。

查看我的帖子在这里:PHP iOS AES加密

我一直在转发这个帖子,因为我一遍又一遍地看到同样的问题。


我刚刚完成了同样的项目。我使用了你在"also considered…"中提到的库。

下面是一些使用php解密的示例代码:

$iv2 = '';
for($i=0;$i<16;$i++){
    $iv2 .= "";   
}
$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模式,但有一个空的初始化向量(iv)。

CBC意味着每个块都依赖于最后一个块,因此它使用一个预先设置的,通常是随机的"块-1",称为IV

ECB意味着每个块都以相同的方式加密,因此它揭示了同一消息中的两个块何时相同。上面提到的库没有使用它,所以我提到它只是为了对比。

使用0 iv(0000000000000000字节)被认为是不安全的,但它确实为您提供了一些额外的安全性(但是人们仍然可以判断每次纯文本的前16个字符是否相同)。要解决这个问题,你必须为iv创建一个NSData *iv变量,并修改NSData+AESCrypt的CCcrypt参数。为iv参数添加[iv字节](我还没有测试过这段代码),你需要存储这个iv,并将它与你的消息一起传递给php。但首先,我将测试并使所有工作与零iv。

相关内容

最新更新