108
社区成员




- <?php
- /**
- * Des 主要操作类
- * @author CuZn
- * @last-modified 2013-4-18
- */
- //加载分组密钥类和辅助函数
- include 'DesKey.class.php';
- include 'TripleDes.class.php';
- include 'toolFunction.php';
- class Des {
- private $DesKey; //DesKey分组密钥对象
- private $contentAdd = 'a'; //文字不足时的添加
- 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 , 'encode' );
- }
- public function decode($content) {
- return $this->authCode($content , 'decode');
- }
- /**
- * 加密的启动函数
- * @param string $type 加密类型
- * @param type $content 加密内容
- * @return type 加密结果
- */
- public function authCode( $content , $type= 'encode') {
- if ($type != 'encode') {
- $type = 'decode';
- }
- $contentEncodeArr = array();
- $contentArr = str_split($content, 8);
- $encodeContent = '';
- 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 = ''; //下轮左半部分输入
- $nextR = ''; //下轮右半部分输入
- $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;
- }
- }
- <?php
- /**
- * Des 生成加密分组密钥
- * @author CuZn
- * @last-modified 2013-4-18
- */
- class DesKey {
- private $key = '';
- private $subKeyArr = array();
- private $keyAdd = 'a';
- 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 = 'encode') {
- if ($method == 'encode') {
- 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);
- }
- }
- }