【问题标题】:AES 128 CBC encryption in PHPPHP 中的 AES 128 CBC 加密
【发布时间】:2025-12-31 18:50:01
【问题描述】:

大家好,我的加密有问题。我创建了一个可以加密用户数据的简单会员注册。但在加密之前,我必须将其格式化为 JSON 格式。但是我在取回正确数据时遇到了问题。当我解码我的代码时。它在 JSON 中有一个多余的字符,这就是我无法获得正确值的原因。但是解密后的JSON数据是正确的。

这是我的目标。

  1. 获取会员的输入数据
  2. 以 JSON 格式格式化数据
  3. 使用 AES 128 CBC 加密对其进行加密(我创建了一个返回数组的函数。一个是加密的,另一个是解密的)
  4. 以纯文本形式显示加密和解密数据

这是我目前的代码。

我的数据加解密功能

public function encryption($data){

    # --- ENCRYPTION ---

    # the key should be random binary, use scrypt, bcrypt or PBKDF2 to
    # convert a string into a key
    # key is specified using hexadecimal
    $key = pack('H*', "73f8d4969098400c44dcb50111eb4193");

    # show key size use either 16, 24 or 32 byte keys for AES-128, 192
    # and 256 respectively
    $key_size =  strlen($key);
    //echo "Key size: " . $key_size . "<br />";

    $plaintext = $data;

    # create a random IV to use with CBC encoding
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);

    # creates a cipher text compatible with AES (Rijndael block size = 128)
    # to keep the text confidential 
    # only suitable for encoded input that never ends with value 00h
    # (because of default zero padding)
    $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,
                                 $plaintext, MCRYPT_MODE_CBC, $iv);

    # prepend the IV for it to be available for decryption
    $ciphertext = $iv . $ciphertext;

    # encode the resulting cipher text so it can be represented by a string
    $ciphertext_base64 = base64_encode($ciphertext);

    //echo  $ciphertext_base64 . "<br />";

    # === WARNING ===

    # Resulting cipher text has no integrity or authenticity added
    # and is not protected against padding oracle attacks.

    # --- DECRYPTION ---

    $ciphertext_dec = base64_decode($ciphertext_base64);

    # retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
    $iv_dec = substr($ciphertext_dec, 0, $iv_size);

    # retrieves the cipher text (everything except the $iv_size in the front)
    $ciphertext_dec = substr($ciphertext_dec, $iv_size);

    # may remove 00h valued characters from end of plain text
    $plaintext_dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
                                    $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec);

    //echo  $plaintext_dec . "<br />";

    $enc_data = array();

    $enc_data['encrypted'] = $ciphertext_base64;
    $enc_data['decrypted'] = $plaintext_dec;

    return $enc_data;

}

流程如下

$a = array();

$a['billing_address'] = array(
    'type' => $var_type1,
    'title' => $this->input->post('title'),
    'address' => $this->input->post('address1'),
    'address2' => $this->input->post('address2'),
    'barangay' => $billing_brgy_name,
    'city' => $billing_city_name,
    'country' => $this->input->post('country'),
    'state' => $this->input->post('state'),
    'zip_code' => $this->input->post('zipcode')
);

$a['shipping_address'] = array(
    'type2' => $var_type2,
    'title2' => $this->input->post('title'),
    'lastname2' => ucwords($this->input->post('lastname2')),
    'firstname2' => ucwords($this->input->post('firstname2')),
    'address1_2' => $this->input->post('address1_2'),
    'address2_2' => $this->input->post('address2_2'),
    'barangay2' => $shipping_brgy_name,
    'city2' => $shipping_city_name,
    'country2' => $this->input->post('country2'),
    'state2' => $this->input->post('state2'),
    'zip_code2' => $this->input->post('zipcode2'),
    'phone' => $this->input->post('tel2_1')
);

$account_info = array(
    'user_id' => NULL,
    'partner_id' => $this->input->post('partner_id'),
    'firstname' => ucwords($this->input->post('firstname')),
    'lastname' => ucwords($this->input->post('lastname')),
    'username' => strtolower($this->input->post('username')),
    'password' => $this->input->post('pass2'),
    'tel1' => $this->input->post('tel1'),
    'tel2' => $this->input->post('tel2'),
    'birthdate' => $timestamp,
    'gender' => $this->input->post('gender'),
    'status' => $this->input->post('status'),
    'addresses' => $a
);

$encode = json_encode($account_info);

$enc = $this->encryption($encode);

$i = $enc['decrypted'];

echo $encode;
print_r(json_decode($encode));
echo $enc['encrypted']."<br />";
echo $enc['decrypted'];

这是示例输出

JSON格式的普通数据

{"user_id":null,"partner_id":"werewr","firstname":"Eqwe","lastname":"Qweqw","username":"wewe123","password":"11111111","tel1":"ewr","tel2":"werwer","birthdate":1386691200,"gender":"M","status":"Separated","addresses":{"billing_address":{"type":"B","title":"Ms.","address":"sdfsdf","address2":"sdfsfd","barangay":"Magsaysay","city":"San Jose","country":"PH","state":"DIN","zip_code":"22"},"shipping_address":{"type2":"S","title2":"Ms.","lastname2":"12312","firstname2":"32132","address1_2":"sdfs","address2_2":"fsdfsd","barangay2":"San Roque","city2":"Pandi","country2":"PH","state2":"BUL","zip_code2":"2323","phone":"12313"}}}

解码后的数据

stdClass Object
(
    [user_id] => 
    [partner_id] => werewr
    [firstname] => Eqwe
    [lastname] => Qweqw
    [username] => wewe123
    [password] => 11111111
    [tel1] => ewr
    [tel2] => werwer
    [birthdate] => 1386691200
    [gender] => M
    [status] => Separated
    [addresses] => stdClass Object
        (
            [billing_address] => stdClass Object
                (
                    [type] => B
                    [title] => Ms.
                    [address] => sdfsdf
                    [address2] => sdfsfd
                    [barangay] => Magsaysay
                    [city] => San Jose
                    [country] => PH
                    [state] => DIN
                    [zip_code] => 22
                )

            [shipping_address] => stdClass Object
                (
                    [type2] => S
                    [title2] => Ms.
                    [lastname2] => 12312
                    [firstname2] => 32132
                    [address1_2] => sdfs
                    [address2_2] => fsdfsd
                    [barangay2] => San Roque
                    [city2] => Pandi
                    [country2] => PH
                    [state2] => BUL
                    [zip_code2] => 2323
                    [phone] => 12313
                )

        )

)

加密数据

7cwUCHUeHy8VNJQ+U7e9oDO51REcf2Y6FANnsTSWOnXAvysfjTWxxg6fq/t9EnDcNNs5+m1QNMGdYNlgWmGhv3e+OEaSVPtvDcHiy/DrqpyPKBAvDqiPUEcrd3Lmu8iGZyiMhv/i+fBDxJI6EQ6WbH6o0N+1j9GC8qmZ5BSdq16TKwEEpzHh4NktNMzGLOMugYhD5yzfD+Uwx2H+VfEb9V4epq1xWqbDUP9DeVOFTP5f8FMkMTbamg20lcRvGSykk4NKhk0VVrpUxr556X99cxP9bhFi7unXhqukZghy/7ZDsTrYQGSGktdrCpdPlqlBNHGWuDp592LIwSCNFHwV2Fyg/10ZjVyHAKWW3I56AHaEwqRdJzbDdNSDttbvyq8VwuPruQv8xXOPMw/L66WJ3PAUxiAywcEyKKbKdo9vxD/RSQTQQti0v+9cw+QrBXpCSLh9K0TDk1MwQiboJWstD6ALzIZQff1Hzr9MRzdsk9zQyxsxJ0DP3n9c3Ks4eWRpEHN7N6m+4KhWPMFMPTIiSKWSJvW1MXRiXEDC+e8nVyOd0ICbBKqPzz/pwbmX4yzmAPxm2zSR7Mp+NwKCPrEijT9ofM7DN619NumA15J9egZ6UOf2ZMac5takgHnF7SIoKmnjOhj1QgdlGN/Emuph2/1rXLEr9+TJ79syqdxuxcTbNo/FhPdW/cdvR5H0Jj2d7wuZ6sXta5IJLpPM7MdgYVpPyOdm/4g2FB31E2dOF3wIZ/zaAlbkRxF9CUyUzIPC512Yk1mUK6o77RzYJlTfE/6x8OZJBOf7ycdz2Ap0gnVzXV4fryM6dxvLkwjI5LhN/CtDZ+3luDX9jGx9RqFUPQn6ronnplCQErHTp83WLnI=

解密后的数据

{"user_id":null,"partner_id":"werewr","firstname":"Eqwe","lastname":"Qweqw","username":"wewe123","password":"11111111","tel1":"ewr","tel2":"werwer","birthdate":1386691200,"gender":"M","status":"Separated","addresses":{"billing_address":{"type":"B","title":"Ms.","address":"sdfsdf","address2":"sdfsfd","barangay":"Magsaysay","city":"San Jose","country":"PH","state":"DIN","zip_code":"22"},"shipping_address":{"type2":"S","title2":"Ms.","lastname2":"12312","firstname2":"32132","address1_2":"sdfs","address2_2":"fsdfsd","barangay2":"San Roque","city2":"Pandi","country2":"PH","state2":"BUL","zip_code2":"2323","phone":"12313"}}}{

当我尝试显示为数组时,结果显示为空白“无数据”。正如您在我的解密数据中看到的那样,有一个多余的“{”字符,这就是我无法获得数组形式的原因。我无法发现我的代码哪里出错了。请大家帮帮我,谢谢。

【问题讨论】:

    标签: php json encryption cryptography


    【解决方案1】:

    好的,我没有设法回答我的问题,但我找到了一个很好且简单的示例,可以将数据加密为 AES 128 CBC 格式。这就是我所拥有的

    public function encrypt($cipher, $key, $iv , $cc) {
    
                mcrypt_generic_init($cipher, $key, $iv);
                $encrypted = base64_encode(mcrypt_generic($cipher,$cc));
                mcrypt_generic_deinit($cipher);
    
                mcrypt_generic_init($cipher, $key, $iv);
                $decrypted = mdecrypt_generic($cipher,base64_decode($encrypted));
                mcrypt_generic_deinit($cipher);
    
                $encrypted_data = array();
                $encrypted_data['encrypt'] = $encrypted;
                $encrypted_data['decrypt'] = $decrypted;
    
                return $encrypted_data;
    
    }
    
    ......
    
                $encode = json_encode($account_info);
    
                $cc = $encode;
                $key = '73f8d4969098400c44dcb50111eb4193';
                $iv =  '1234567890123456';
                $length = strlen($cc);
    
                $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'','cbc','');
    
                $h = $this->encrypt($cipher, $key, $iv, $cc);
    
                $enc_data = $h['encrypt'];
                $dec_data = substr($h['decrypt'], 0, $length);
    
                echo $enc_data."\n";
                echo $dec_data."\n";
    

    希望它也能帮助到你。 :)

    【讨论】: