• 全部
...

基于EEE3模式的3DES算法加密和解密实现

ChengKaoAO 2016-12-08 01:36:12
EEE3表示3个密钥。
具体要求如下:
(1)实现3DES算法的加密和解密,完成DES加密过程,输入明文,能加密得到正确密文(密文以十六进制显示)。完成DES解密过程,输入密文(十六进制),能解密得到正确明文(字符形式)。
(2)明文加密之后密文,必须能正确解密出相应明文
(3)明文尾部必须进行填充。例如ECB模式下,DES算法8个字符一组,若输入10个字符“1111111111”,则需要分为2组,第1组8个字符,第2组2个字符,则需要填充。若输入8个字符“11111111”,刚好1组,则需要填充增加1组明文。
(4)尾部填充方法为除最后一个字符填充字符数,其余全填充为“0”字符。例如输入明文“1111111111”,第1组明文输入“11111111”,第二组填充之后明文“11000006”。如输入明文“11111111”,第1组明文输入“11111111”,第二组填充之后明文“00000008”。
(5)DES算法加密和解密,调用变换函数完成。
(6)操作简单,界面美观。
输出要求:
(1)用函数实现把字符与二进制相互转换过程,并输出转换后的结果;用函数实现十六进制与二进制相互转换过程。
(2)中间结果包括:3DES算法中,3次调用加密或解密的输出(十六进制)。
编程要求:C、php、java.
3desPHP代码参考开源中国:
https://www.oschina.net/code/snippet_221804_20525
Des.class.php

  1. <?php

  2. /**
  3. * Des 主要操作类
  4. * @author CuZn
  5. * @last-modified 2013-4-18
  6. */
  7. //加载分组密钥类和辅助函数
  8. include 'DesKey.class.php';
  9. include 'TripleDes.class.php';
  10. include 'toolFunction.php';

  11. class Des {

  12. private $DesKey; //DesKey分组密钥对象
  13. private $contentAdd = 'a'; //文字不足时的添加
  14. private $permutationETable = array(//置换表E
  15. 32, 1, 2, 3, 4, 5,
  16. 4, 5, 6, 7, 8, 9,
  17. 8, 9, 10, 11, 12, 13,
  18. 12, 13, 14, 15, 16, 17,
  19. 16, 17, 18, 19, 20, 21,
  20. 20, 21, 22, 23, 24, 25,
  21. 24, 25, 26, 27, 28, 29,
  22. 28, 29, 30, 31, 32, 1
  23. );
  24. private $permutationPTable = array(//置换表P
  25. 16, 7, 20, 21, 29, 12, 28, 17,
  26. 1, 15, 23, 26, 5, 18, 31, 10,
  27. 2, 8, 24, 14, 32, 27, 3, 9,
  28. 19, 13, 30, 6, 22, 11, 4, 25
  29. );
  30. private $sBox = array(//S盒子
  31. array(
  32. 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  33. 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  34. 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  35. 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
  36. ),
  37. array(
  38. 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  39. 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  40. 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  41. 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
  42. ),
  43. array(
  44. 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  45. 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  46. 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  47. 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
  48. ),
  49. array(
  50. 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  51. 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  52. 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  53. 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
  54. ),
  55. array(
  56. 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  57. 14, 11, 2, 12, 4, 7, 15, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  58. 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  59. 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
  60. ),
  61. array(
  62. 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  63. 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  64. 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  65. 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
  66. ),
  67. array(
  68. 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  69. 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  70. 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  71. 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
  72. ),
  73. array(
  74. 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  75. 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  76. 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  77. 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
  78. )
  79. );

  80. public function __construct($key) {
  81. $this->DesKey = new DesKey($key);
  82. }

  83. public function encode($content) {
  84. return $this->authCode($content , 'encode' );
  85. }

  86. public function decode($content) {
  87. return $this->authCode($content , 'decode');
  88. }

  89. /**
  90. * 加密的启动函数
  91. * @param string $type 加密类型
  92. * @param type $content 加密内容
  93. * @return type 加密结果
  94. */
  95. public function authCode( $content , $type= 'encode') {
  96. if ($type != 'encode') {
  97. $type = 'decode';
  98. }

  99. $contentEncodeArr = array();
  100. $contentArr = str_split($content, 8);

  101. $encodeContent = '';

  102. for ($index = 0; $index < count($contentArr); $index++) {
  103. $content = $contentArr[$index];
  104. if (strlen($content) < 8) {
  105. $content .= str_repeat($this->contentAdd, ( 8 - strlen($content)));


  106. }
  107. $contentBitArr = bytesToBitArr($content);
  108. list($L, $R) = array_chunk($contentBitArr, 32);

  109. $contentEncodeArr = $this->_run($L, $R, $type);

  110. $byteArr = array_chunk($contentEncodeArr, 8);

  111. for ($index1 = 0; $index1 < count($byteArr); $index1++) {
  112. $byte = 0;
  113. for ($i = 0; $i < count($byteArr[$index1]); $i++) {
  114. $byte += $byteArr[$index1][$i] * pow(2, 7 - $i);
  115. }
  116. $encodeContent .= chr($byte);
  117. }
  118. }

  119. return $encodeContent;
  120. }

  121. /**
  122. * Feistel 结构加密算法中的迭代函数
  123. * @param type $L 32位的左半部分输入
  124. * @param type $R 32位的右半部分输入
  125. * @param type $method encode(加密)或decode(解密)
  126. * @param type $round 迭代的轮数
  127. * @return type
  128. */
  129. private function _run($L, $R, $method = "encode", $round = 0) {
  130. $nextL = ''; //下轮左半部分输入
  131. $nextR = ''; //下轮右半部分输入

  132. $subKey48Bit = $this->DesKey->getSubKeyAt($round, $method); //子密钥
  133. $FResult32Bit = $this->_F($subKey48Bit, $R); //轮函数结果
  134. //异或
  135. for ($index = 0; $index < count($FResult32Bit); $index++) {
  136. $FResult32Bit[$index] = $FResult32Bit[$index] === $L[$index] ? false : true;
  137. }

  138. $nextL = $R;
  139. $nextR = $FResult32Bit;

  140. //轮数将会停在15,共加密16轮
  141. if ($round >= 15) {
  142. return array_merge($nextR, $nextL);
  143. } else {
  144. return $this->_run($nextL, $nextR, $method, ++$round);
  145. }
  146. }

  147. /**
  148. * Feitel架构中的轮函数
  149. * @param type $subKey48Bit 48位的子密钥
  150. * @param type $R 当前轮的右部分输入
  151. * @return 32位结果
  152. */
  153. public function _F($subKey48Bit, $R) {
  154. $tmp48Bit = array();

  155. //E表置换
  156. for ($index = 0; $index < count($this->permutationETable); $index++) {
  157. $tmp48Bit[] = $R[$this->permutationETable[$index] - 1];
  158. }

  159. //与子密钥异或
  160. for ($index = 0; $index < count($tmp48Bit); $index++) {
  161. $tmp48Bit[$index] = $tmp48Bit[$index] === $subKey48Bit[$index] ? false : true;
  162. }

  163. //代替/选择(s盒)
  164. $tem32Bit = array();
  165. $tem6BitArr = array_chunk($tmp48Bit, 6);
  166. for ($index = 0; $index < count($tem6BitArr); $index++) {
  167. $tem6Bit = $tem6BitArr[$index];

  168. $line = $tem6Bit[0] * 2 + $tem6Bit[5] * 1;
  169. $field = $tem6Bit[1] * 2 * 2 * 2 + $tem6Bit[2] * 2 * 2 + $tem6Bit[3] * 2 + $tem6Bit[4];
  170. $selectPos = $line * 6 + $field;

  171. $select = $this->sBox[$index][$selectPos];
  172. if ($select >= 8) {
  173. $tem32Bit[] = true;
  174. } else {
  175. $tem32Bit[] = false;
  176. }
  177. $select %= 8;
  178. if ($select >= 4) {
  179. $tem32Bit[] = true;
  180. } else {
  181. $tem32Bit[] = false;
  182. }
  183. $select %= 4;
  184. if ($select >= 2) {
  185. $tem32Bit[] = true;
  186. } else {
  187. $tem32Bit[] = false;
  188. }
  189. $select %=2;
  190. if ($select >= 1) {
  191. $tem32Bit[] = true;
  192. } else {
  193. $tem32Bit[] = false;
  194. }
  195. }

  196. //置换P
  197. $FResult32Bit = array();
  198. for ($index = 0; $index < count($this->permutationPTable); $index++) {
  199. $FResult32Bit[] = $tem32Bit[$this->permutationPTable[$index] - 1];
  200. }

  201. return $FResult32Bit;
  202. }

  203. }


DesKey.class.php
  1. <?php

  2. /**
  3. * Des 生成加密分组密钥
  4. * @author CuZn
  5. * @last-modified 2013-4-18
  6. */
  7. class DesKey {

  8. private $key = '';
  9. private $subKeyArr = array();
  10. private $keyAdd = 'a';
  11. private $CkeyArr = array();
  12. private $dkeyArr = array();
  13. private $leftShiftArr = array(1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1);
  14. private $permutationTable = array(
  15. 14, 17, 11, 24, 1, 5, 3, 28,
  16. 15, 6, 21, 10, 23, 19, 13, 4,
  17. 26, 8, 16, 7, 27, 20, 13, 2,
  18. 41, 52, 31, 37, 47, 55, 30, 40,
  19. 51, 45, 33, 48, 44, 49, 39, 56,
  20. 34, 53, 46, 42, 50, 36, 29, 32
  21. ); //置换表

  22. public function __construct($key) {
  23. $this->_initKey($key);
  24. $this->_generateSubKey();
  25. }
  26. /**
  27. * 获取指定位置的子密钥
  28. * @param type $index 位置
  29. * @param type $method 决定是正序还是逆序
  30. * @return type 48bit的子密钥
  31. */
  32. public function getSubKeyAt($index, $method = 'encode') {
  33. if ($method == 'encode') {
  34. return $this->subKeyArr[$index];
  35. } else {
  36. return $this->subKeyArr[15 - $index];
  37. }
  38. }

  39. /**
  40. * 初始化64位的密钥
  41. * @param type $key 字符密钥
  42. */
  43. private function _initKey($key) {
  44. $key = substr($key, 0, 8);
  45. $keyLen = strlen($key);
  46. //补全64位
  47. if ($keyLen < 8) {
  48. $key .= str_repeat($this->keyAdd, 8 - $keyLen);
  49. }

  50. $this->key = $key;

  51. $bitArr = bytesToBitArr($this->key);

  52. //初始化C0,左边取28位
  53. for ($index = 0; $index < 32; $index++) {
  54. if ($index % 8 === 7) {
  55. continue;
  56. }
  57. $this->CkeyArr[] = $bitArr[$index];
  58. }

  59. //初始化D0,右边取28位
  60. for ($index = 32; $index < 64; $index++) {
  61. if ($index % 8 === 7) {
  62. continue;
  63. }
  64. $this->DkeyArr[] = $bitArr[$index];
  65. }
  66. }

  67. /**
  68. * 16轮生成16个子密钥
  69. * @param type $round 当前轮数
  70. */
  71. private function _generateSubKey($round = 0) {
  72. //左移
  73. $tmp28BitC = array_shift($this->CkeyArr);
  74. $tmp28BitD = array_shift($this->DkeyArr);
  75. $this->CkeyArr[] = $tmp28BitC;
  76. $this->DkeyArr[] = $tmp28BitD;
  77. //是否继续左移
  78. if ($this->leftShiftArr[$round] == 2) {
  79. $tmp28BitC = array_shift($this->CkeyArr);
  80. $tmp28BitD = array_shift($this->DkeyArr);
  81. $this->CkeyArr[] = $tmp28BitC;
  82. $this->DkeyArr[] = $tmp28BitD;
  83. }

  84. $tem56BitCDkey = array_merge($this->CkeyArr, $this->DkeyArr);
  85. $tem48BitSubkey = array();
  86. //置换&压缩
  87. for ($index = 0; $index < count($this->permutationTable); $index++) {
  88. $tem48BitSubkey[] = $tem56BitCDkey[$this->permutationTable[$index] - 1];
  89. }
  90. $this->subKeyArr[] = $tem48BitSubkey;

  91. if ($round < 15) {
  92. $this->_generateSubKey(++$round);
  93. }
  94. }

  95. }


toolFunction.php


...全文
给本帖投票
3119 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ChengKaoAO 2017-08-12
  • 打赏
  • 举报
回复
也就是单倍长的DES加密、解密亦就是DES加密的这一过程,如果没有其它特殊要求的话,可以通过调用PHP的内置加密DES的加密函数(encryptMode)直接实现加解密(decryptMode)过程。
逸嘉鱼 2017-05-04
  • 打赏
  • 举报
回复
想问一下单倍长des加解密,怎么实现?
GWLCGL520 2016-12-12
  • 打赏
  • 举报
回复
厉害了,word哥
赵4老师 2016-12-09
  • 打赏
  • 举报
回复

108

社区成员

发帖
与我相关
我的任务
社区描述
本论坛将作为用户和华为FusionInsight大数据平台的开发交流平台,我们将持续建设本论坛,致力于让用户更好更快更全面的了解华为FusionInsight大数据平台。
华为华为云 技术论坛(原bbs)
社区管理员
  • FusionInsight HD社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧

手机看
关注公众号

关注公众号

客服 返回
顶部