如何使 openssl_encrypt 将输入填充到所需的块大小?

Posted

技术标签:

【中文标题】如何使 openssl_encrypt 将输入填充到所需的块大小?【英文标题】:How do I make openssl_encrypt pad the input to the required block size? 【发布时间】:2017-07-01 21:27:56 【问题描述】:

如果我手动将字符串填充到 32 的长度,我的代码就可以工作。 我的问题是:有没有办法让 openSSL 填充数据,还是我总是必须这样做?

工作:

 openssl_encrypt ("my baba is over the ocean1111111", 'AES-256-CBC', $MY_SECRET_KEY,OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING,$MY_IV);

不工作:

openssl_encrypt ("my baba is over the ocean", 'AES-256-CBC', $MY_SECRET_KEY,OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING,$MY_IV);

我目前通过自填充解决了这个问题:

$pad = 32 - (strlen("my baba is over the ocean") % 32);
$clear = "my baba is over the ocean" . str_repeat(chr($pad), $pad); //encrypt this string

【问题讨论】:

AES 所需的块大小为 16。我猜您选择的 0 填充会使机器感到困惑。 你能不故意使用 PKCS5 作为你的填充方案来代替你目前有零填充的地方吗? @LukePark 有内置的方法吗?顺便说一句 -> 请注意我自己填充块而不是零 【参考方案1】:

正如 Luke Park 所说,与其明确告诉openssl_encrypt 使用OPENSSL_ZERO_PADDING,不如从参数中删除该选项,它将默认为PKCS #7 padding scheme(用0x0n 填充块的其余部分,其中n 是必要的字节数;+ 16 0x00 如果块已经完成)。 注意:Luke 引用的 PKCS #5 和 PKCS #7 在这种情况下实际上是相同的。

来自php docs:

不使用 OPENSSL_ZERO_PADDING,您将自动获得 PKCS#7 填充。

所以你应该打电话:

openssl_encrypt("my baba is over the ocean", 'AES-256-CBC', $MY_SECRET_KEY, OPENSSL_RAW_DATA, $MY_IV);

【讨论】:

让我感到困惑的是名称,我认为这意味着用零填充。虽然实际上它的意思是没有填充。 我想用这个方法生成一个URL字符串的一部分。但是生成的 URL 由系统无法理解的随机字节组成。打印出来时出现乱码。在这种情况下还有其他解决方案吗? 您应该使用 URL 安全编码对密文进行编码,例如 hexadecimal 或 Base64(对 URL 进行修改)。

以上是关于如何使 openssl_encrypt 将输入填充到所需的块大小?的主要内容,如果未能解决你的问题,请参考以下文章

使D3堆积条形图填充父SVG容器

如何使文本框扩展以填充网格单元的剩余空间?

使用php openssl_encrypt的正确方法

使用 Crypto 将 PHP openssl_encrypt 与 md5 转换为 NodeJS

视图设计问题:如何使滚动视图的子视图填充屏幕?

如何使 textarea 填充 div 块?