PHP 基礎(chǔ)篇 - PHP 中 DES 加解密詳解

一、簡(jiǎn)介

DES 是對(duì)稱性加密里面常見(jiàn)一種,全稱為 Data Encryption Standard合呐,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法笙以。密鑰長(zhǎng)度是64位(bit)淌实,超過(guò)位數(shù)密鑰被忽略。所謂對(duì)稱性加密即加密和解密密鑰相同,對(duì)稱性加密一般會(huì)按照固定長(zhǎng)度拆祈,把待加密字符串分成塊恨闪,不足一整塊或者剛好最后有特殊填充字符。

跨語(yǔ)言做 DES 加密解密經(jīng)常會(huì)出現(xiàn)問(wèn)題缘屹,往往是填充方式不對(duì)凛剥、編碼不一致或者加密解密模式?jīng)]有對(duì)應(yīng)上造成。常見(jiàn)的填充模式有: pkcs5轻姿、pkcs7、iso10126逻炊、ansix923互亮、zero。加密模式有:DES-ECB余素、DES-CBC豹休、DES-CTR、DES-OFB桨吊、DES-CFB威根。

作為一個(gè)軟件開(kāi)發(fā)者,可以通過(guò)工具測(cè)試 DES 加密解密视乐,這里推薦一個(gè)在線工具:http://tool.chacuo.net/cryptdes

二洛搀、實(shí)現(xiàn)

PHP 提供了 Mcrypt 系列函數(shù)來(lái)實(shí)現(xiàn) DES 的加解密,但該擴(kuò)展中的函數(shù)陸續(xù)被廢棄佑淀,自 PHP 7.2.0 起留美,會(huì)移到 PECL。

所以本代碼用了更通用的 OPENSSL 方式實(shí)現(xiàn) DES 的加解密伸刃,具體的實(shí)現(xiàn)和使用代碼如下:

<?php

/**
 * openssl 實(shí)現(xiàn)的 DES 加密類谎砾,支持各種 PHP 版本
 */
class DES
{
    /**
     * @var string $method 加解密方法,可通過(guò) openssl_get_cipher_methods() 獲得
     */
    protected $method;

    /**
     * @var string $key 加解密的密鑰
     */
    protected $key;

    /**
     * @var string $output 輸出格式 無(wú)捧颅、base64景图、hex
     */
    protected $output;

    /**
     * @var string $iv 加解密的向量
     */
    protected $iv;

    /**
     * @var string $options
     */
    protected $options;

    // output 的類型
    const OUTPUT_NULL = '';
    const OUTPUT_BASE64 = 'base64';
    const OUTPUT_HEX = 'hex';


    /**
     * DES constructor.
     * @param string $key
     * @param string $method
     *      ECB DES-ECB、DES-EDE3 (為 ECB 模式時(shí)碉哑,$iv 為空即可)
     *      CBC DES-CBC挚币、DES-EDE3-CBC、DESX-CBC
     *      CFB DES-CFB8谭梗、DES-EDE3-CFB8
     *      CTR
     *      OFB
     *
     * @param string $output
     *      base64忘晤、hex
     *
     * @param string $iv
     * @param int $options
     */
    public function __construct($key, $method = 'DES-ECB', $output = '', $iv = '', $options = OPENSSL_RAW_DATA | OPENSSL_NO_PADDING)
    {
        $this->key = $key;
        $this->method = $method;
        $this->output = $output;
        $this->iv = $iv;
        $this->options = $options;
    }

    /**
     * 加密
     *
     * @param $str
     * @return string
     */
    public function encrypt($str)
    {
        $str = $this->pkcsPadding($str, 8);
        $sign = openssl_encrypt($str, $this->method, $this->key, $this->options, $this->iv);

        if ($this->output == self::OUTPUT_BASE64) {
            $sign = base64_encode($sign);
        } else if ($this->output == self::OUTPUT_HEX) {
            $sign = bin2hex($sign);
        }

        return $sign;
    }

    /**
     * 解密
     *
     * @param $encrypted
     * @return string
     */
    public function decrypt($encrypted)
    {
        if ($this->output == self::OUTPUT_BASE64) {
            $encrypted = base64_decode($encrypted);
        } else if ($this->output == self::OUTPUT_HEX) {
            $encrypted = hex2bin($encrypted);
        }

        $sign = @openssl_decrypt($encrypted, $this->method, $this->key, $this->options, $this->iv);
        $sign = $this->unPkcsPadding($sign);
        $sign = rtrim($sign);
        return $sign;
    }

    /**
     * 填充
     *
     * @param $str
     * @param $blocksize
     * @return string
     */
    private function pkcsPadding($str, $blocksize)
    {
        $pad = $blocksize - (strlen($str) % $blocksize);
        return $str . str_repeat(chr($pad), $pad);
    }

    /**
     * 去填充
     * 
     * @param $str
     * @return string
     */
    private function unPkcsPadding($str)
    {
        $pad = ord($str{strlen($str) - 1});
        if ($pad > strlen($str)) {
            return false;
        }
        return substr($str, 0, -1 * $pad);
    }

}


$key = 'key123456';
$iv = 'iv123456';

// DES CBC 加解密
$des = new DES($key, 'DES-CBC', DES::OUTPUT_BASE64, $iv);
echo $base64Sign = $des->encrypt('Hello DES CBC');
echo "\n";
echo $des->decrypt($base64Sign);
echo "\n";

// DES ECB 加解密
$des = new DES($key, 'DES-ECB', DES::OUTPUT_HEX);
echo $base64Sign = $des->encrypt('Hello DES ECB');
echo "\n";
echo $des->decrypt($base64Sign);

三、相關(guān)鏈接


本文首發(fā)于馬燕龍個(gè)人博客激捏,歡迎分享设塔,轉(zhuǎn)載請(qǐng)標(biāo)明出處。
馬燕龍個(gè)人博客:http://www.mayanlong.com
馬燕龍個(gè)人微博:http://weibo.com/imayanlong
馬燕龍Github主頁(yè):https://github.com/yanlongma

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闰蛔,隨后出現(xiàn)的幾起案子痕钢,更是在濱河造成了極大的恐慌,老刑警劉巖序六,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件任连,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡例诀,警方通過(guò)查閱死者的電腦和手機(jī)随抠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)繁涂,“玉大人拱她,你說(shuō)我怎么就攤上這事∪幼铮” “怎么了秉沼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)矿酵。 經(jīng)常有香客問(wèn)我唬复,道長(zhǎng),這世上最難降的妖魔是什么全肮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任敞咧,我火速辦了婚禮,結(jié)果婚禮上倔矾,老公的妹妹穿的比我還像新娘妄均。我一直安慰自己,他們只是感情好哪自,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布丰包。 她就那樣靜靜地躺著,像睡著了一般壤巷。 火紅的嫁衣襯著肌膚如雪邑彪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天胧华,我揣著相機(jī)與錄音寄症,去河邊找鬼。 笑死矩动,一個(gè)胖子當(dāng)著我的面吹牛有巧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悲没,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼篮迎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起甜橱,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤逊笆,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后岂傲,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體难裆,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年镊掖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了乃戈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亩进,死狀恐怖偏化,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镐侯,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布驶冒,位于F島的核電站苟翻,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏骗污。R本人自食惡果不足惜崇猫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望需忿。 院中可真熱鬧诅炉,春花似錦、人聲如沸屋厘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汗洒。三九已至议纯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間溢谤,已是汗流浹背瞻凤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留世杀,地道東北人阀参。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瞻坝,于是被迫代替她去往敵國(guó)和親蛛壳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 隨著對(duì)于安全度的不斷要求赫模,對(duì)于數(shù)據(jù)加解密與破解之間的斗爭(zhēng)树肃,加解密的方式也在不斷發(fā)生著變化,來(lái)看看現(xiàn)在流行的一些加解...
    zhouhao_180閱讀 2,080評(píng)論 1 12
  • 本文主要介紹移動(dòng)端的加解密算法的分類瀑罗、其優(yōu)缺點(diǎn)特性及應(yīng)用胸嘴,幫助讀者由淺入深地了解和選擇加解密算法。文中會(huì)包含算法的...
    蘋(píng)果粉閱讀 11,500評(píng)論 5 29
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理斩祭,服務(wù)發(fā)現(xiàn)劣像,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 最近公司業(yè)務(wù)需要用到公鑰和私鑰,之前接觸的很少,不是很了解,剛剛上網(wǎng)了解了下.發(fā)現(xiàn)很多地方都要用到加密.有對(duì)稱加密...
    左神話閱讀 2,242評(píng)論 0 2
  • 為你而筑的城 胤歆 我筑了一座城 備好了鳳冠和永恒 待你來(lái)許下的是一生 燭火微昏 思念抓著回憶苦等...
    胤歆閱讀 347評(píng)論 0 0