PHP版DES演算法加密資料
阿新 • • 發佈:2020-12-04
php7之前的版本
function encrypt($input) { if (version_compare(PHP_VERSION, '7.0.0') >= 0) { $size = 16; $k = C('KEY_LONG'); $input = pkcs5_pad($input, $size); $data = openssl_encrypt($input, 'AES-128-CBC', $k, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $k); } else { $size = 8; $k = C('KEY_SHORT'); $input = pkcs5_pad($input, $size); $td = mcrypt_module_open(MCRYPT_DES, '', 'cbc', ''); mcrypt_generic_init($td, $k, $k); $data = mcrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); } $data = base64_encode($data); return $data; } function decrypt($input) { $crypt = base64_decode($input); if (version_compare(PHP_VERSION, '7.0.0') >= 0) { $size = 16; $k = C('KEY_LONG'); $data = openssl_decrypt($crypt, 'AES-128-CBC', $k, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $k); } else { $size = 8; $k = C('KEY_SHORT'); $td = mcrypt_module_open(MCRYPT_DES, '', 'cbc', ''); mcrypt_generic_init($td, $k, $k); $data = mdecrypt_generic($td, $crypt); mcrypt_generic_deinit($td); mcrypt_module_close($td); } $data = pkcs5_unpad($data); $data = rtrim($data); return $data; } function pkcs5_pad($_var_308, $_var_309) { $_var_310 = $_var_309 - strlen($_var_308) % $_var_309; return $_var_308 . str_repeat(chr($_var_310), $_var_310); } function pkcs5_unpad($_var_308) { $_var_310 = ord($_var_308[strlen($_var_308) - 1]); if ($_var_310 > strlen($_var_308)) { return false; } return substr($_var_308, 0, -1 * $_var_310); }
php7之後的版本
class Des { private static $_instance = NULL; var $key;//祕鑰向量 var $iv;//混淆向量 ->偏移量 function __construct() { $this->key = env('DES_KEY'); $this->iv = env('DES_IV'); } /** * * @User yaokai * @return Des|null */ public static function share() { if (is_null(self::$_instance)) { self::$_instance = new Des(); } return self::$_instance; } /** * 加密演算法 * @User yaokai * @param $input 要加密的資料 * @return string 返回加密後的字串 */ function encrypt($input) { //獲得加密演算法的分組大小 8 $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC); //3DES加密將MCRYPT_DES改為MCRYPT_3DES //ascii 填充 $input = $this->pkcs5_pad($input, $size); //如果採用PaddingPKCS7,請更換成PaddingPKCS7方法。 //用0填充祕鑰為指定長度8 $key = str_pad($this->key, 8, '0'); //3DES加密將8改為24 //開啟演算法和模式對應的模組 $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, ''); //判斷混淆向量是否為空 if ($this->iv == '') { //從演算法源隨機生成混淆向量 $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);//類似b"¨ß^\f\x1EÅ╩5" } else { //反之取設定的混淆向量 $iv = $this->iv; } //初始化加密所需的緩衝區 @mcrypt_generic_init($td, $key, $iv); //加密資料 $td為演算法物件模組 $input為處理過後的值 $data = mcrypt_generic($td, $input);// 類似b"ýyP\x7FN\x00èiÝd>À?s\x18Î" //對加密模組進行清理工作 mcrypt_generic_deinit($td); //關閉加密模組 mcrypt_module_close($td); //使用 MIME base64 對資料進行編碼 $data = base64_encode($data);//如需轉換二進位制可改成 bin2hex 轉換 //如果設定了混淆向量 則加密的值是固定的 如果沒設定混淆向量 則加密的值是隨機的 return $data; } /** * 解密演算法 * @User yaokai * @param $encrypted 加密後的字串 * @return bool|string */ function decrypt($encrypted) { //對使用 MIME base64 編碼的資料進行解碼 $encrypted = base64_decode($encrypted); //如需轉換二進位制可改成 bin2hex 轉換 //使用另一個字串填充字串為指定長度 獲取祕鑰 $key = str_pad($this->key, 8, '0'); //3DES加密將8改為24 //開啟演算法和模式對應的模組 $td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');//3DES加密將MCRYPT_DES改為MCRYPT_3DES //判斷混淆向量是否為空 if ($this->iv == '') { //從演算法源隨機生成混淆向量 $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); } else { //反之取設定的混淆向量 $iv = $this->iv; } //返回開啟的模式所能支援的最長金鑰 沒用上 $ks = mcrypt_enc_get_key_size($td);//DES 8 3DES 24 //初始化加密所需的緩衝區 @mcrypt_generic_init($td, $key, $iv); //解密資料 $td為演算法物件模組 $encrypted為需要解密的資料 $decrypted = mdecrypt_generic($td, $encrypted);//類似於 "15549070665\x05\x05\x05\x05\x05" 之前加密的資料 //對加密模組進行清理工作 mcrypt_generic_deinit($td); //關閉加密模組 mcrypt_module_close($td); //返回取出解密資料 $data = $this->pkcs5_unpad($decrypted); return $data; } /** * 填補需加密的字串 * PKCS7Padding VS PKCS5Padding * 區別,PKCS5Padding的blocksize為8位元組,而PKCS7Padding的blocksize可以為1到255位元組 * @User yaokai * @param $text * @param $blocksize * @return string */ function pkcs5_pad($text, $blocksize) { //$pad=5 blocksize=11 $test=8 %取餘 $pad = $blocksize - (strlen($text) % $blocksize);//5 //返回ascii填補後的字串, 類似 "15549070665\x05\x05\x05\x05\x05" return $text . str_repeat(chr($pad), $pad); } /** * 去除加密填補的字串 * PKCS7Padding VS PKCS5Padding * 區別,PKCS5Padding的blocksize為8位元組,而PKCS7Padding的blocksize可以為1到255位元組 * @User yaokai * @param $text * @return bool|string */ function pkcs5_unpad($text) { //取出最後一個字串 {15} ord返回字元的 ASCII 碼值 $pad = ord($text{strlen($text) - 1});//5 //判斷$pad的值是否大於本身字串 if ($pad > strlen($text)) { //如果大於 則多餘 return false; } //計算ASCII 碼值中全部字元都存在於$text字元集合中的第一段子串的長度是否等於取出的$pad if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) { //如果不相等 則缺失 return false; } //返回字串的子串 return substr($text, 0, -1 * $pad); } /** * 填補需加密的字串 * PKCS7Padding VS PKCS5Padding * 區別,PKCS5Padding的blocksize為8位元組,而PKCS7Padding的blocksize可以為1到255位元組 * @User yaokai * @param $text * @param $blocksize * @return string */ function PaddingPKCS7($data) { $block_size = mcrypt_get_block_size(MCRYPTDES, MCRYPT_MODE_CBC);//3DES加密將MCRYPT_DES改為MCRYPT_3DES $padding_char = $block_size - (strlen($data) % $block_size); $data .= str_repeat(chr($padding_char), $padding_char); return $data; } /** * 去除加密填補的字串 * PKCS7Padding VS PKCS5Padding * 區別,PKCS5Padding的blocksize為8位元組,而PKCS7Padding的blocksize可以為1到255位元組 * @User yaokai * @param $text * @return bool|string */ private function UnPaddingPKCS7($text) { $pad = ord($text{strlen($text) - 1}); if ($pad > strlen($text)) { return false; } if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) { return false; } return substr($text, 0, -1 * $pad); } }