PHP实现AES加密并使用PKCS7填充

前言

如题,最近在寻找这个实现方案,但是找到的方案都是使用 Mcrypt。然而,Mcrypt 系列函数从 PHP 7.1.0 开始就被弃用了,而我又找不到其他方案。于是我就去查阅了 PKCS7 的具体填充方式,自行实现。

Mcrypt系列函数已被弃用

介绍

PKCS7 (公钥密码学标准第 7 号)
PKCS#7 定义于 RFC 5652 (征求意见草案第 5652 号)。

每个填充字节的值是用于填充的字节数,即是说,若需要填充 N 个字节,则每个填充字节值都是 N 。 填充的字节数取决于算法可以处理的最小数据块的字节数量。

01
02 02
03 03 03
04 04 04 04
05 05 05 05 05
etc.

例:下例中,块大小为 8 字节,需要填充 4 字节。

... | DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

以上为摘录部分,原文: PKCS7 填充

了解其具体的填充方式后,就可以着手实现了。

实现

自行编写一个填充函数。

function padPkcs7($data, $blocksize = 16)
{
    $pad = $blocksize - (strlen($data) % $blocksize);
    return $data . str_repeat(chr($pad), $pad);
}

使用示例

$plaintext = "Hello world!";
$cipher_algo = 'aes-128-ecb';
$key = '0123456789abcdef';

// PKCS7 填充
$data = padPkcs7($plaintext);

$ciphertext = openssl_encrypt($data, $cipher_algo, $key, OPENSSL_DONT_ZERO_PAD_KEY | OPENSSL_ZERO_PADDING);

后记

在评论中又提到一种方案

$plaintext = "Hello world!";
$cipher_algo = 'aes-128-ecb';
$key = '0123456789abcdef';

$ciphertext = openssl_encrypt($plaintext, $cipher_algo, $key);

实测与上面的方法结果一样,但是不知道当时为什么没用这种方案...

本文链接:

https://blog.nkxingxh.top/archives/308/
  • OωO
  • |´・ω・)ノ
  • ヾ(≧∇≦*)ゝ
  • (☆ω☆)
  • (╯‵□′)╯︵┴─┴
  •  ̄﹃ ̄
  • (/ω\)
  • ∠( ᐛ 」∠)_
  • (๑•̀ㅁ•́ฅ)
  • →_→
  • ୧(๑•̀⌄•́๑)૭
  • ٩(ˊᗜˋ*)و
  • (ノ°ο°)ノ
  • (´இ皿இ`)
  • ⌇●﹏●⌇
  • (ฅ´ω`ฅ)
  • (╯°A°)╯︵○○○
  • φ( ̄∇ ̄o)
  • ヾ(´・ ・`。)ノ"
  • ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
  • (ó﹏ò。)
  • Σ(っ °Д °;)っ
  • ( ,,´・ω・)ノ"(´っω・`。)
  • ╮(╯▽╰)╭
  • o(*////▽////*)q
  • >﹏<
  • ( ๑´•ω•) "(ㆆᴗㆆ)
  • (。•ˇ‸ˇ•。)
  • 😂
  • 😀
  • 😅
  • 😊
  • 🙂
  • 🙃
  • 😌
  • 😍
  • 😘
  • 😜
  • 😝
  • 😏
  • 😒
  • 🙄
  • 😳
  • 😡
  • 😔
  • 😫
  • 😱
  • 😭
  • 💩
  • 👻
  • 🙌
  • 🖕
  • 👍
  • 👫
  • 👬
  • 👭
  • 🌚
  • 🌝
  • 🙈
  • 💊
  • 😶
  • 🙏
  • 🍦
  • 🍉
  • 😣
  • 颜文字
  • Emoji
1 + 8 =
5 评论
    qazFirefox Browser 123Windows 10
    2024年03月08日 回复

    openssl_pkcs7_encrypt 不了解下吗?

      NKXingXhChrome 122Windows 10
      2024年03月10日 回复

      @qaz 这个函数读取输入文件并使用 RC2 40 位的密码将之加密,而我需要的是AES加密。

        qazFirefox Browser 123Windows 10
        2024年03月11日 回复

        @NKXingXh 是我没搞清你的PHP版本、openssl版本,是我先入为主了,想当然了。
        openssl_encrypt($plain, 'AES-128-ECB', $key, OPENSSL_RAW_DATA, $iv);

        ヾ(≧∇≦*)ゝ

          NKXingXhChrome 122Windows 10
          2024年03月11日 回复

          @qaz 目前实测了这个 $ciphertext = openssl_encrypt($plaintext, $cipher_algo, $key); 确实是可以与文中的方法得到一样的结果,但是不知道当时试了挺多为什么没发现

        qazFirefox Browser 123Windows 10
        2024年03月11日 回复

        @NKXingXh PHP_OPENSSL_CIPHER_DEFAULT = PHP_OPENSSL_CIPHER_AES_CBC

        ୧(๑•̀⌄•́๑)૭