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

ChengKaoAO 2016-12-08 03:04:08
要求如下:
实现3DES算法EEE3。
(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等实现控制台编程语言

参考开源社区实现3des的纯PHP文档:
https://www.oschina.net/code/snippet_221804_20525

example.php

<?php
include 'Des.class.php';

$str = "aabcdefqrssdfsdfsdfsdfsdfasreguiowefisdfsdfsdfhldfsnasdhfuit";

$Des = new Des('12345678');
$encode = $Des->encode($str);
echo "<br/>Des加密结果:<br/>";
echo $encode;
$decode = $Des->decode($encode);
echo "<br/>Des解密结果:<br/>";
echo $decode;

$TripleDes = new TripleDes('12345678','abcdefgh');
$encode = $TripleDes->encode($str);
echo "<br/>3Des加密结果:<br/>";
echo $encode;
$decode = $TripleDes->decode($encode);
echo "<br/>3Des解密结果:<br/>";
echo $decode;
?>

Des.class.php
<?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( $type , $content= '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;
}

}
...全文
596 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ChengKaoAO 2017-08-12
  • 打赏
  • 举报
回复
谢谢!已解决!!!
_明月 2016-12-08
  • 打赏
  • 举报
回复
真的抱歉,由于我个人能力有限,真的帮不了你。

319

社区成员

发帖
与我相关
我的任务
社区描述
2016华为开发者大赛(HUAWEI Developer Challenge 2016) 是华为公司面向全国开发者的大型软件竞赛,帮助开发者实现业务创新落地,成就开发者创新梦想,软件正在改变世界
个人开发开源软件软件构建 技术论坛(原bbs)
社区管理员
  • 华为开发者大赛社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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