【问题标题】:Using phpseclib AES to encrypt string使用 phpseclib AES 加密字符串
【发布时间】:2016-09-04 03:56:49
【问题描述】:

好的,这是来自页面http://phpseclib.sourceforge.net/crypt/examples.html的示例代码

<?php
include('Crypt/AES.php');
include('Crypt/Random.php');

$cipher = new Crypt_AES(); // could use CRYPT_AES_MODE_CBC
// keys are null-padded to the closest valid size
// longer than the longest key and it's truncated
//$cipher->setKeyLength(128);
$cipher->setKey('abcdefghijklmnop');
// the IV defaults to all-NULLs if not explicitly defined
$cipher->setIV(crypt_random_string($cipher->getBlockLength() >> 3));

$size = 10 * 1024;
$plaintext = str_repeat('a', $size);

echo $cipher->decrypt($cipher->encrypt($plaintext));
?>

在任何事情之前,为什么//$cipher-&gt;setKeyLength(128); 行被注释掉了?

如果我想将我的密钥设置为“1234568790”,我应该怎么做?因为它比上面示例中的密钥长度短得多(abcdefghijklmnop)。

最后,如果我要加密的明文很短,比如“我的名字是詹姆斯邦德”,我还需要做些什么吗?因为从上面的代码看来,明文的长度应该是 10 x 1024。(为什么?)

【问题讨论】:

  • 纯文本不应该是 10x1024,他们只是创建了一个大小为 10KB 的字符串(因此为 10x1024),例如目的。 128 位密钥意味着 128 / 8 个字节 = 16 个字节,每个字符 2 个字节,相当于 8 个字符。 256 位密钥 = 32 字节 = 16 个字符(因此 abcdefghijklmnop 是 16 个字符)。我个人对您找到的那个特定库并不太熟悉 - 我更喜欢 openssl 扩展而不是纯 php 库。
  • @Mjh 感谢您的评论。但是当我将其设置为 128 位时,页面中的示例会将密钥显示为 abcdefghijklmnop ......这是 128 位密钥的 16 个字符
  • 不必使用这些字符。密钥也可以转换为十六进制格式(通过散列),然后可以使用相应的字节数。就个人而言,我使用的密钥总是随机创建然后散列的——使用的散列函数是根据密码的块大小选择的。加密是一头复杂的野兽,而且通常没有正确实施(训练有素的加密人员会在我发布的评论中发现错误)。在您进一步了解加密之前,我建议您使用this blog。最好从一开始就做。
  • 哇,在您提供的链接中好好阅读。谢谢!

标签: php encryption phpseclib


【解决方案1】:

在任何事情之前,为什么//$cipher-&gt;setKeyLength(128); 行被注释掉了?

假设您通过setKey 将一个 17 字节的密钥传递给 phpseclib。你认为应该发生什么?在 1.0 和 2.0 版本中,如果 setKeyLength 没有被调用,那么密钥被空填充到 24 个字节(例如 192 位)。但是如果setKeyLength is 被调用,它将被截断为 16 个字节。在主分支(据我了解,最终将成为 3.0 分支)中,如果密钥长度无效,则会引发异常。在该版本中,如果您想在代码的一部分中将密钥长度设置为 128 位,然后在代码的另一部分中实际设置密钥,则可能仍需要调用 setKeyLength。 IE。你可以做长度检查或者 phpseclib 可以做长度检查。

如果我想将我的密钥设置为“1234568790”,我应该怎么做?因为它比上面示例中的密钥长度短得多(abcdefghijklmnop)。

1234568790 在技术上不足以成为有效密钥。它有 80 个字节长。 AES 支持的最小密钥是 128 位。也许您应该考虑使用setPassword('1234568790') 而不是setKey('1234568790')setPassword 将使用密钥派生函数从密码生成密钥。

在 phpseclib 1.0 和 2.0 中,setKey 将接受它作为密钥。它只会空填充键。主分支 otoh 将抛出异常,因为密钥实际上不够长。

最后,如果我要加密的明文很短,比如“我的名字是詹姆斯邦德”,我还需要做些什么吗?因为从上面的代码看来,明文的长度应该是 10 x 1024。(为什么?)

10 * 1024 只是一个例子。默认情况下,phpseclib 将使用 PKCS7 填充来使字符串足够长。例如。您的字符串长 21 个字节(如果我计算正确的话)。因此,如果您调用$cipher-&gt;encrypt('my name is james bond'),那么chr(11) 将通过phpseclib 附加到明文11 次,然后字符串将被加密。这是因为块算法需要明文是块长度的倍数。所以密文的长度为 32 个字节。然后,当您调用$cipher-&gt;decrypt('...') 时,您将得到原始的 21 字节字符串。我可以进一步详细说明 PKCS7 填充,但我想我已经回答了你的直接问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多