PHP7.* AES的加密解密

之前寫過一篇:

PHP AES的加密解密-----【棄用】

使用的是php5.*之前的mcrypt_decrypt 函數,該函數已經在php7.1後棄用了,上馬的是openssl的openssl_encrypt,openssl_decrypt。

上期回顧

在php7.* 環境執行之前代碼:

<?php

define('SECRETKEY', '12f862d21d3ceafba1b88e5f22960d55');

/**
 * 加密方法
 * @param string $str
 * @return string
 */
function encrypt($str) {
    //AES, 128 ECB模式加密數據
    
   
    $str = addPKCS7Padding($str);
    
    $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);  # MCRYPT_RAND 隨機, 固定爲 16個0
    define('A', $iv);
    $encrypt_str = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC, $iv);
    return base64_encode($encrypt_str);
}

/**
 * 解密方法
 * @param string $str
 * @return string
 */
function decrypt($str) {
    //AES, 128 ECB模式加密數據
    $str = base64_decode($str);
    $encrypt_str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, SECRETKEY, $str, MCRYPT_MODE_CBC,A);
    $encrypt_str = stripPKSC7Padding($encrypt_str);
    return $encrypt_str;
}

/**
 * 填充算法
 * @param string $source
 * @return string
 */
function addPKCS7Padding($source) {
    $source = trim($source);
    $block = mcrypt_get_block_size('rijndael-128', 'cbc');
    $pad = $block - (strlen($source) % $block);
    if ($pad <= $block) {
        $char = chr($pad);
        $source .= str_repeat($char, $pad);
    }
    return $source;
}

/**
 * 移去填充算法
 * @param string $source
 * @return string
 */
function stripPKSC7Padding($source) {
    $char = substr($source, -1);
    $num = ord($char);
    $source = substr($source, 0, -$num);
    return $source;
}




/**
 *  加密
 */
$string =encrypt('Hello, world!');
print_r($string);
echo '<hr>';
/**
 *  解密
 */
$string=decrypt($string);
print_r($string);

打印:

Deprecated: Function mcrypt_get_block_size() is deprecated in /home/wwwroot/web/html/php/a.php on line 42

Deprecated: Function mcrypt_get_iv_size() is deprecated in /home/wwwroot/web/html/php/a.php on line 16

Deprecated: Function mcrypt_create_iv() is deprecated in /home/wwwroot/web/html/php/a.php on line 16

Deprecated: Function mcrypt_encrypt() is deprecated in /home/wwwroot/web/html/php/a.php on line 18
HUou9juETJVsWw8RxA8qkKH1+zf5zy283ApG6yzW/rU=

Deprecated: Function mcrypt_decrypt() is deprecated in /home/wwwroot/web/html/php/a.php on line 30
Hello, world!

 

看看php官網的解釋:http://php.net/manual/zh/function.mcrypt-encrypt.php

 

 那句話怎麼說的“mcrypt_decrypt要靠php自我奮鬥,但也要考慮歷史的進程。”,時代不一樣了openssl當道啦!

 

openssl的加密解密

之前我們用mcrypt_decrypt 實現的代碼,現在openssl兩行代碼就能實現。

/**
 * openssl 實現
 */
define('KEY', '12f862d21dcfeafb57bckfrrt5yuiopf');
$iv= md5(time(). uniqid(),true);
$str="Hello, world!";
# 加密 md5->true 爲16位md5
echo $strEncode= base64_encode(openssl_encrypt($str, 'AES-128-CBC',KEY, OPENSSL_RAW_DATA , $iv));   # AES-256-CBC

/**
 * 解密
 */
echo "<hr>";
echo openssl_decrypt(base64_decode($strEncode), 'AES-128-CBC', KEY, OPENSSL_RAW_DATA, $iv);

 打印結果:

 

注意!

 上面代碼有沒有發現問題:

偏移向量iv的長度必須爲16位,比如整個19位回報錯:

Warning: openssl_encrypt(): IV passed is 19 bytes long which is longer than the 16 expected by selected cipher,

method 長度的問題,密碼學方式我們用的最多的有兩種,AES-128-CBC 與 AES-256-CBC

上節我們講過字符串的長度問題

1 bit 位    = 1  二進制數據
1 byte 字節  = 8  bit
1 字母 = 1  byte = 8 bit

128位/8=16字節=16字符
192位/8=24字節=24字符
256位/8=32字節=32字符

也就是說KEY 的長度是根據AES-128-CBC 與 AES-256-CBC 變換的。使用 AES-128-CBC 時,key的長度應該爲16位,使用 AES-256-CBC時,key的長度應該爲32位。

 

 

當然了,如果key長度大於限定方式,也無所謂,不是我說無所謂,是php在處理的時候只截取實際的長度。如果長度不夠php也會使用‘x00’填補。

所以上面的代碼key長度是錯誤的,因爲用的是AES-128-CBC,所以key長度應該爲16位。對! 我就是故意的。

 

轉自:PHP7.* AES的加密解密

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章