Heim > php教程 > PHP源码 > 纯php实现DES以及TripleDES加密算法

纯php实现DES以及TripleDES加密算法

PHP中文网
Freigeben: 2016-05-25 17:06:09
Original
1719 Leute haben es durchsucht

1.example/php

<?php
include &#39;Des.class.php&#39;;
 
$str = "aabcdefqrssdfsdfsdfsdfsdfasreguiowefisdfsdfsdfhldfsnasdhfuit";
 
$Des = new Des(&#39;12345678&#39;);
$encode = $Des->encode($str);
echo "<br/>Des加密结果:<br/>";
echo $encode;
$decode = $Des->decode($encode);
echo "<br/>Des解密结果:<br/>";
echo $decode;
 
$TripleDes = new TripleDes(&#39;12345678&#39;,&#39;abcdefgh&#39;);
$encode = $TripleDes->encode($str);
echo "<br/>3Des加密结果:<br/>";
echo $encode;
$decode = $TripleDes->decode($encode);
echo "<br/>3Des解密结果:<br/>";
echo $decode;
?>
Nach dem Login kopieren

2.tripledes.class.php

<?php
 
/**
 * TripleDes 三次Des加密
 * @author CuZn 
 * @last-modified 2013-4-18
 */
class TripleDes {
 
    private $DesArr = array();
 
    public function __construct($key1, $key2) {
        $this->DesArr[] = new Des($key1);
        $this->DesArr[] = new Des($key2);
    }
 
    public function encode($content) {
        return $this->DesArr[0]->encode(
                        $this->DesArr[1]->decode(
                                $this->DesArr[0]->encode($content)
                        )
        );
    }
     
    public function decode($content) {
        return $this->DesArr[0]->decode(
                        $this->DesArr[1]->encode(
                                $this->DesArr[0]->decode($content)
                        )
        );
    }
 
}
 
?>
Nach dem Login kopieren

3.des.class.php

<?php
 
/**
 * Des 主要操作类
 * @author CuZn 
 * @last-modified 2013-4-18
 */
//加载分组密钥类和辅助函数
include &#39;DesKey.class.php&#39;;
include &#39;TripleDes.class.php&#39;;
include &#39;toolFunction.php&#39;;
 
class Des {
 
    private $DesKey; //DesKey分组密钥对象
    private $contentAdd = &#39;a&#39;; //文字不足时的添加
    private $permutationETable = array(//置换表E
        32, 1, 2, 3, 4, 5,
        4, 5, 6, 7, 8, 9,
        8, 9, 10, 11, 12, 13,
        12, 13, 14, 15, 16, 17,
        16, 17, 18, 19, 20, 21,
        20, 21, 22, 23, 24, 25,
        24, 25, 26, 27, 28, 29,
        28, 29, 30, 31, 32, 1
    );
    private $permutationPTable = array(//置换表P
        16, 7, 20, 21, 29, 12, 28, 17,
        1, 15, 23, 26, 5, 18, 31, 10,
        2, 8, 24, 14, 32, 27, 3, 9,
        19, 13, 30, 6, 22, 11, 4, 25
    );
    private $sBox = array(//S盒子
        array(
            14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
            0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
            4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
            15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
        ),
        array(
            15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
            3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
            0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
            13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
        ),
        array(
            10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
            13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
            13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
            1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
        ),
        array(
            7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
            13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
            10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
            3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
        ),
        array(
            2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
            14, 11, 2, 12, 4, 7, 15, 1, 5, 0, 15, 10, 3, 9, 8, 6,
            4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
            11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
        ),
        array(
            12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
            10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
            9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
            4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
        ),
        array(
            4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
            13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
            1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
            6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
        ),
        array(
            13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
            1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
            7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
            2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
        )
    );
 
    public function __construct($key) {
        $this->DesKey = new DesKey($key);
    }
 
    public function encode($content) {
        return $this->authCode($content , &#39;encode&#39; );
    }
 
    public function decode($content) {
        return $this->authCode($content , &#39;decode&#39;);
    }
 
    /**
     * 加密的启动函数
     * @param string $type 加密类型
     * @param type $content 加密内容
     * @return type 加密结果
     */
    public function authCode( $content , $type = &#39;encode&#39;) {
        if ($type != &#39;encode&#39;) {
            $type = &#39;decode&#39;;
        }
 
        $contentEncodeArr = array();
        $contentArr = str_split($content, 8);
 
        $encodeContent = &#39;&#39;;
 
        for ($index = 0; $index < count($contentArr); $index++) {
            $content = $contentArr[$index];
            if (strlen($content) < 8) {
                $content .= str_repeat($this->contentAdd, ( 8 - strlen($content)));
 
 
            }
            $contentBitArr = bytesToBitArr($content);
            list($L, $R) = array_chunk($contentBitArr, 32);
 
            $contentEncodeArr = $this->_run($L, $R, $type);
 
            $byteArr = array_chunk($contentEncodeArr, 8);
 
            for ($index1 = 0; $index1 < count($byteArr); $index1++) {
                $byte = 0;
                for ($i = 0; $i < count($byteArr[$index1]); $i++) {
                    $byte += $byteArr[$index1][$i] * pow(2, 7 - $i);
                }
                $encodeContent .= chr($byte);
            }
        }
 
        return $encodeContent;
    }
 
    /**
     * Feistel 结构加密算法中的迭代函数
     * @param type $L 32位的左半部分输入
     * @param type $R 32位的右半部分输入
     * @param type $method encode(加密)或decode(解密) 
     * @param type $round 迭代的轮数
     * @return type
     */
    private function _run($L, $R, $method = "encode", $round = 0) {
        $nextL = &#39;&#39;; //下轮左半部分输入
        $nextR = &#39;&#39;; //下轮右半部分输入
 
        $subKey48Bit = $this->DesKey->getSubKeyAt($round, $method); //子密钥
        $FResult32Bit = $this->_F($subKey48Bit, $R); //轮函数结果
        //异或
        for ($index = 0; $index < count($FResult32Bit); $index++) {
            $FResult32Bit[$index] = $FResult32Bit[$index] === $L[$index] ? false : true;
        }
 
        $nextL = $R;
        $nextR = $FResult32Bit;
 
        //轮数将会停在15,共加密16轮
        if ($round >= 15) {
            return array_merge($nextR, $nextL);
        } else {
            return $this->_run($nextL, $nextR, $method, ++$round);
        }
    }
 
    /**
     * Feitel架构中的轮函数
     * @param type $subKey48Bit 48位的子密钥
     * @param type $R 当前轮的右部分输入
     * @return 32位结果
     */
    public function _F($subKey48Bit, $R) {
        $tmp48Bit = array();
 
        //E表置换
        for ($index = 0; $index < count($this->permutationETable); $index++) {
            $tmp48Bit[] = $R[$this->permutationETable[$index] - 1];
        }
 
        //与子密钥异或
        for ($index = 0; $index < count($tmp48Bit); $index++) {
            $tmp48Bit[$index] = $tmp48Bit[$index] === $subKey48Bit[$index] ? false : true;
        }
 
        //代替/选择(s盒)
        $tem32Bit = array();
        $tem6BitArr = array_chunk($tmp48Bit, 6);
        for ($index = 0; $index < count($tem6BitArr); $index++) {
            $tem6Bit = $tem6BitArr[$index];
 
            $line = $tem6Bit[0] * 2 + $tem6Bit[5] * 1;
            $field = $tem6Bit[1] * 2 * 2 * 2 + $tem6Bit[2] * 2 * 2 + $tem6Bit[3] * 2 + $tem6Bit[4];
            $selectPos = $line * 6 + $field;
 
            $select = $this->sBox[$index][$selectPos];
            if ($select >= 8) {
                $tem32Bit[] = true;
            } else {
                $tem32Bit[] = false;
            }
            $select %= 8;
            if ($select >= 4) {
                $tem32Bit[] = true;
            } else {
                $tem32Bit[] = false;
            }
            $select %= 4;
            if ($select >= 2) {
                $tem32Bit[] = true;
            } else {
                $tem32Bit[] = false;
            }
            $select %=2;
            if ($select >= 1) {
                $tem32Bit[] = true;
            } else {
                $tem32Bit[] = false;
            }
        }
 
        //置换P
        $FResult32Bit = array();
        for ($index = 0; $index < count($this->permutationPTable); $index++) {
            $FResult32Bit[] = $tem32Bit[$this->permutationPTable[$index] - 1];
        }
 
        return $FResult32Bit;
    }
 
}
Nach dem Login kopieren

4.deskey.class.php

<?php
 
/**
 * Des 生成加密分组密钥
 * @author CuZn 
 * @last-modified 2013-4-18
 */
class DesKey {
 
    private $key = &#39;&#39;;
    private $subKeyArr = array();
    private $keyAdd = &#39;a&#39;;
    private $CkeyArr = array();
    private $dkeyArr = array();
    private $leftShiftArr = array(1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);
    private $permutationTable = array(
        14, 17, 11, 24, 1, 5, 3, 28,
        15, 6, 21, 10, 23, 19, 13, 4,
        26, 8, 16, 7, 27, 20, 13, 2,
        41, 52, 31, 37, 47, 55, 30, 40,
        51, 45, 33, 48, 44, 49, 39, 56,
        34, 53, 46, 42, 50, 36, 29, 32
    ); //置换表
 
    public function __construct($key) {
        $this->_initKey($key);
        $this->_generateSubKey();
    }
    /**
     * 获取指定位置的子密钥
     * @param type $index 位置
     * @param type $method 决定是正序还是逆序
     * @return type 48bit的子密钥
     */
    public function getSubKeyAt($index, $method = &#39;encode&#39;) {
        if ($method == &#39;encode&#39;) {
            return $this->subKeyArr[$index];
        } else {
            return $this->subKeyArr[15 - $index];
        }
    }
 
    /**
     * 初始化64位的密钥
     * @param type $key 字符密钥
     */
    private function _initKey($key) {
        $key = substr($key, 0, 8);
        $keyLen = strlen($key);
        //补全64位
        if ($keyLen < 8) {
            $key .= str_repeat($this->keyAdd, 8 - $keyLen);
        }
 
        $this->key = $key;
 
        $bitArr = bytesToBitArr($this->key);
 
        //初始化C0,左边取28位
        for ($index = 0; $index < 32; $index++) {
            if ($index % 8 === 7) {
                continue;
            }
            $this->CkeyArr[] = $bitArr[$index];
        }
         
        //初始化D0,右边取28位
        for ($index = 32; $index < 64; $index++) {
            if ($index % 8 === 7) {
                continue;
            }
            $this->DkeyArr[] = $bitArr[$index];
        }
    }
     
    /**
     * 16轮生成16个子密钥
     * @param type $round 当前轮数
     */
    private function _generateSubKey($round = 0) {
        //左移
        $tmp28BitC = array_shift($this->CkeyArr);
        $tmp28BitD = array_shift($this->DkeyArr);
        $this->CkeyArr[] = $tmp28BitC;
        $this->DkeyArr[] = $tmp28BitD;
        //是否继续左移
        if ($this->leftShiftArr[$round] == 2) {
            $tmp28BitC = array_shift($this->CkeyArr);
            $tmp28BitD = array_shift($this->DkeyArr);
            $this->CkeyArr[] = $tmp28BitC;
            $this->DkeyArr[] = $tmp28BitD;
        }
         
        $tem56BitCDkey = array_merge($this->CkeyArr, $this->DkeyArr);
        $tem48BitSubkey = array();
        //置换&压缩
        for ($index = 0; $index < count($this->permutationTable); $index++) {
            $tem48BitSubkey[] = $tem56BitCDkey[$this->permutationTable[$index] - 1];
        }
        $this->subKeyArr[] = $tem48BitSubkey;
         
        if ($round < 15) {
            $this->_generateSubKey(++$round);
        }
    }
 
}
Nach dem Login kopieren

5.toolfunction.php

<?php
 
/**
 * 将字节流转换成数组
 * @param type $bytes
 * @return boolean 数组
 */
function bytesToBitArr($bytes) {
    $boolArr = array();
 
        for ($i = 0; $i < strlen($bytes); $i++) {
            $byte = substr($bytes, $i, 1);
            for ($index = 0; $index < 8; $index++) {
                if (((ord($byte) << $index) % 256) >= 128) {
                    $boolArr[] = true;
                } else {
                    $boolArr[] = false;
                }
            }
        }
 
        return $boolArr;
    }
 
    /**
     * 测试用
     * @param type $bitArr
     */
    function dumpBit($bitArr) {
        for ($index = 0; $index < count($bitArr); $index++) {
            if ($bitArr[$index]) {
                echo &#39;1&#39;;
            } else {
                echo &#39;0&#39;;
            }
        }
 
        echo &#39;<br />&#39;;
    }
 
    /**
     * 测试用
     * @param type $num
     * @param type $str
     */
    function testDesTime($num = 100, $str = &#39;测试测试&#39;) {
        $startPoint = microtimeFloat();
        for ($index = 0; $index < $num; $index++) {
            $Des = new Des(&#39;12345678&#39;);
            $encode = $Des->encode($str);
        }
        $endPoint = microtimeFloat();
        $allTime = $endPoint - $startPoint;
        return $allTime;
    }
 
    /**
     * 测试用
     * @param type $num
     * @param type $str
     */
    function testMd5Time($num = 100, $str = &#39;测试测试&#39;) {
        $startPoint = microtimeFloat();
        for ($index = 0; $index < $num; $index++) {
            $encode = md5($str);
        }
        $endPoint = microtimeFloat();
 
        $allTime = $endPoint - $startPoint;
        return $allTime;
    }
 
    /**
     * 测试用
     * @param type $num
     * @param type $str
     */
    function microtimeFloat() {
        list($usec, $sec) = explode(" ", microtime());
        return ((float) $usec + (float) $sec);
    }
Nach dem Login kopieren
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage