代码改进版:
# =============================================
# 安全邮件系统实现 - 结合DES和RSA加密
# 功能:实现安全的消息加密、签名和传输
# =============================================
# --------------------------
# 第一部分:消息准备和加密
# --------------------------
# 原始消息内容
message := "This is an attempt to look at a reasonable way to send a message...";
# 1. 消息预处理
# --------------------------
# 计算消息长度(字符数)
messLength := length(message);
# 计算需要的64位(8字节)块数量(向上取整)
messWords := ceil(messLength/8);
# 计算需要填充的字节数使消息长度为8的倍数
messPadding := 8*messWords - messLength;
# 将消息转换为ASCII字节列表
messList := convert(message, bytes):
# 添加零填充使消息长度为8的倍数
messList := [op(messList),seq(0,i=1..messPadding)]:
# 定义辅助函数:将整数转换为2位16进制字符串
intTo2Hex := intVal -> substring(convert(intVal+256,hex),2..3):
# 将字节列表转换为16进制字符串列表
messHexList := map(intTo2Hex,messList):
# 将16进制列表分组为8字节(64位)的字
messHexWordList := [seq(cat(seq(messHexList[8*i+j],j=1..8)),i=0..messWords-1)]:
# 2. DES加密准备
# --------------------------
# 生成随机64位DES密钥(16位16进制)
randKey := substring(convert(2^64+rand(2^64)(),hex),2..17); # 例如 "7778EEFFF432E596"
# 扩展DES密钥(生成16个子密钥)
key := keyexpander(randKey):
# 3. DES-CBC模式加密
# --------------------------
# 初始化向量(IV) - 加密全零块作为IV
allZeroes := "0000000000000000";
IV := qdDEShex(allZeroes,key);
# 创建表存储密文块
cipherTable := table():
# 加密第一个块: E(P1 XOR IV)
cipherTable[1] := qdDEShex(xor64hex(IV,messHexWordList[1]),key);
# 加密后续块: E(Pi XOR C(i-1))
for i from 2 to messWords do
cipherTable[i] := qdDEShex(xor64hex(cipherTable[i-1],messHexWordList[i]),key):
od:
# 将密文表转换为列表
cipherList := [seq(cipherTable[i],i=1..messWords)];
# --------------------------
# 第二部分:数字签名
# --------------------------
# 4. 使用RSA创建数字签名
# 使用最后一个密文块作为消息摘要
hash := cipherList[messWords]; # 例如 "7C54E08D43AEC1AF"
# 生成发送方的RSA密钥对
# 选择两个大素数(约80位)
p := nextprime(rand(10^80)());
q := nextprime(rand(10^80)());
# 计算模数n
Sendern := p*q;
# 公钥指数(通常选择65537)
Sendere := 2^16+1;
# 计算私钥指数d ≡ e⁻¹ mod (p-1)(q-1)
Senderd := (1/Sendere) mod ((p-1)*(q-1));
# 将哈希值转换为十进制大整数
digestNum := convert(hash, decimal, hex);
# 使用私钥签名: S = H^d mod n
signature := Power(digestNum,Senderd) mod Sendern;
# 将签名转换为16进制
sigHex := convert(signature, hex);
# --------------------------
# 第三部分:会话密钥加密
# --------------------------
# 5. 使用接收方公钥加密DES会话密钥
# 假设已获得接收方公钥 (Receivere, Receivern)
# 将DES密钥转换为十进制大整数
keyNum := convert(randKey, decimal, hex);
# 使用接收方公钥加密: C = K^e mod n
encryptKey := Power(keyNum, Receivere) mod Receivern:
# 将加密后的密钥转换为16进制
encryptKeyHex := convert(encryptKey, hex);
# 现在可以安全传输以下数据:
# 1. cipherList - 加密的消息
# 2. sigHex - 数字签名
# 3. encryptKeyHex - 加密的DES密钥
# 4. 发送方公钥 (Sendere, Sendern)
# =============================================
# 第四部分:解密过程
# =============================================
# 1. 验证数字签名
# --------------------------
# 将签名转换回十进制
signature := convert(sigHex, decimal, hex):
# 使用发送方公钥验证签名: H' = S^e mod n
sigD := Power(signature,Sendere) mod Sendern;
# 将结果转换为16进制字符串
hashRecover := substring(convert(2^64+sigD,hex),2..17);
# 验证签名是否匹配
if hashRecover = cipherList[messWords] then
print("签名验证成功 - 消息来自可信发送方且未被篡改");
else
print("签名验证失败 - 消息可能被篡改或来源不可信");
fi;
# 2. 恢复DES会话密钥
# --------------------------
# 将加密的密钥转换回十进制
encryptKey := convert(encryptKeyHex,decimal,hex):
# 使用接收方私钥解密: K = C^d mod n
keyNum := Power(encryptKey, Receiverd) mod Receivern:
# 将解密后的密钥转换为16进制字符串
sessionKey := substring(convert(keyNum + 2^64, hex),2..17); # 应与原始randKey相同
# 3. DES-CBC模式解密
# --------------------------
# 扩展DES密钥
key := keyexpander(sessionKey):
# 重新生成初始化向量(与加密时相同)
IV := qdDEShex("0000000000000000",key):
# 创建表存储解密后的明文块
plainTable := table():
# 解密第一个块: P1 = D(C1) XOR IV
plainTable[1] := xor64hex(unDEShex(cipherList[1],key), IV):
# 解密后续块: Pi = D(Ci) XOR C(i-1)
for i from 2 to messWords do
plainTable[i] := xor64hex(unDEShex(cipherList[i],key), cipherList[i-1]);
od:
# 将解密后的块转换为列表
plainList := [seq(plainTable[i],i=1..messWords)];
# 4. 转换为原始消息
# --------------------------
# 将每个16进制字转换为8个字节
plainListBytes := map(x -> seq(convert(substring(x,2*i+1..2*i+2),decimal,hex),i=0..7), plainList):
# 将字节列表转换为ASCII字符
received := convert(plainListBytes,bytes);
# 移除填充的零字节
received := received[1..messLength];
# 输出解密结果
print("解密后的原始消息:");
convert(received,bytes);
# =============================================
# 辅助函数说明(需要预先实现):
#
# 1. keyexpander(key) - DES密钥扩展算法
# 输入: 64位密钥(16位16进制字符串)
# 输出: 16个48位子密钥
#
# 2. qdDEShex(block, key) - DES加密函数
# 输入: 64位数据块和扩展后的密钥
# 输出: 64位密文块
#
# 3. unDEShex(block, key) - DES解密函数
# 输入: 64位密文块和扩展后的密钥
# 输出: 64位明文块
#
# 4. xor64hex(a, b) - 64位16进制字符串异或
# 输入: 两个64位(16字符)16进制字符串
# 输出: 异或结果(16字符16进制字符串)
# =============================================
系统概述
目标
1. 通过开放信道安全发送加密消息
2. 防止窃听
3. 接收方能验证发送方身份
4. 确保消息未被篡改(完整性和真实性)
技术组合
- **DES**:对称块加密算法,用于加密消息内容
- **RSA**:公钥加密算法,用于加密会话密钥和数字签名
加密过程详解
1. 准备消息
```maple
message := "This is an attempt to look at a reasonable way to send a message...";
```
消息包含说明文本,描述了该系统的工作原理。
2. DES加密准备
```maple
messLength := length(message); // 计算消息长度(577字符)
messWords := ceil(messLength/8); // 计算需要的64位字数量(73个)
messPadding := 8*messWords - messLength; // 计算需要填充的字节数(7个)
```
将消息转换为字节列表并填充:
```maple
messList := convert(message, bytes):
messList := [op(messList),seq(0,i=1..messPadding)]:
```
转换为16进制表示:
```maple
intTo2Hex := intVal -> substring(convert(intVal+256,hex),2..3):
messHexList := map(intTo2Hex,messList):
messHexWordList := [seq(cat(seq(messHexList[8*i+j],j=1..8)),i=0..messWords-1)]:
```
3. DES-CBC模式加密
生成随机DES密钥:
```maple
randKey := substring(convert(2^64+rand(2^64)(),hex),2..17); // "7778EEFFF432E596"
```
初始化向量(IV):
```maple
allZeroes := "0000000000000000";
IV := qdDEShex(allZeroes,key); // 加密全零块作为IV
```
执行CBC模式加密:
```maple
cipherTable[1] := qdDEShex(xor64hex(IV,messHexWordList[1]),key);
for i from 2 to messWords do
cipherTable[i] := qdDEShex(xor64hex(cipherTable[i-1],messHexWordList[i]),key):
od:
```
4. 数字签名
使用RSA对消息哈希(最后一个密文块)签名:
```maple
hash := cipherList[messWords]; // "7C54E08D43AEC1AF"
// 生成RSA密钥对
p := nextprime(rand(10^80)()); // 大素数p
q := nextprime(rand(10^80)()); // 大素数q
Sendern := p*q; // 模数n
Sendere := 2^16+1; // 公钥指数e
Senderd := (1/Sendere) mod ((p-1)*(q-1)); // 私钥d
// 对哈希签名
digestNum := convert(hash, decimal, hex);
signature := Power(digestNum,Senderd) mod Sendern;
sigHex := convert(signature, hex);
```
5. 加密会话密钥
//使用接收方的公钥加密DES会话密钥:
keyNum := convert(randKey, decimal, hex);
encryptKey := Power(keyNum, Receivere) mod Receivern:
encryptKeyHex := convert(encryptKey, hex);
解密过程详解
1. 验证签名
//验证签名
signature := convert(sigHex, decimal, hex):
sigD := Power(signature,Sendere) mod Sendern; // 使用发送方公钥验证
hashRecover := substring(convert(2^64+sigD,hex),2..17);
2. 恢复会话密钥
//恢复会话密钥
encryptKey := convert(encryptKeyHex,decimal,hex):
keyNum := Power(encryptKey, Receiverd) mod Receivern: // 使用接收方私钥解密
sessionKey := substring(convert(keyNum + 2^64, hex),2..17); // "7778EEFFF432E596"
3. DES-CBC模式解密
//DES-CBC模式解密
key := keyexpander(sessionKey):
IV := qdDEShex("0000000000000000",key):
// CBC模式解密
plainTable[1] := xor64hex(unDEShex(cipherList[1],key), IV):
for i from 2 to messWords do
plainTable[i] := xor64hex(unDEShex(cipherList[i],key), cipherList[i-1]);
od:
// 转换回原始消息
plainListBytes := map(x -> seq(convert(substring(x,2*i+1..2*i+2),decimal,hex),i=0..7), plainList):
received := convert(plainListBytes,bytes);
## 练习题目
1. 解密给定消息并验证签名,然后构造加密回复
2. 创建自己的10行消息,生成DES和RSA密钥,完成加密和签名过程
3. 测试自己的消息能否正确解密
4. 与同学交换公钥,实现安全邮件通信
## 技术要点总结
1. **混合加密系统**:结合DES(高效)和RSA(安全密钥交换)
2. **CBC模式**:增加加密安全性,防止模式分析
3. **数字签名**:使用RSA确保消息真实性和完整性
4. **密钥管理**:会话密钥随机生成,用接收方公钥加密
5. **填充处理**:确保消息长度符合DES块大小要求