PHP版DES算法加密數據(3DES)另附openssl_encrypt版本


PHP版DES算法加密數據(3DES)

可與java的DES(DESede/CBC/PKCS5Padding)加密方式兼容

<?php
/**
 * Created by PhpStorm.
 * Title:PHP版DES加解密類
 *        可與java的DES(DESede/CBC/PKCS5Padding)加密方式兼容
 * User: yaokai
 * Date: 2017/11/13 0013
 * Time: 19:03
 */
 
namespace App\Http\Libs;
 
 
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);
    }
 
 
}

 

由於php7.1廢棄了mcrypt_* 一系列函數 所以采用 openssl版本

/**
* des3加密
* @author bug  <375023402@qq.com>
* @createtime 2019-04-17 17:30:53
* @param $str 要加密的數據
* @param $des_key 秘鑰向量
* @param $des_iv 混淆向量 ->偏移量
* @return 
*/
if(!function_exists('des3_encrypt')){
  function des3_encrypt($str,$des_key="",$des_iv="")
  {
      return base64_encode(openssl_encrypt($str, 'des-ede3-cbc', $des_key, OPENSSL_RAW_DATA, $des_iv));
  }
}

 

感謝csdn版主  https://blog.csdn.net/xzykai/article/details/78932206

如有侵權請聯系刪除修改


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM