密码学Chapter7、8作业
Chapter7 思考题
7.1 什么是三重加密?
使用三个不同的密钥进行三次加密
7.3 在三重加密中用到了多少个密钥?
两密钥或三密钥
7.4 为什么3DES的中间部分采用解密而非加密?
这样做的好处是当你用
k
1
=
k
2
=
k
3
=
k
k_1=k_2=k_3=k
k1=k2=k3=k
代入
C
=
E
(
k
3
,
D
(
k
2
,
E
(
k
1
,
m
)
)
)
C=E(k_3,D(k_2,E(k_1,m)))
C=E(k3,D(k2,E(k1,m)))
里面两层的D和E消去,3DES就会变成普通的DES
7.5 为什么某些分组密码的操作模式只使用加密算法而其他模式既使用加密算法又使用解密算法?
出于加密与解密的考虑,一个密码模式必须保证加密与解密的可逆性。
在密码分组链接模式中,对明文与前一密文分组异或后加密,在解密时就要先解密再异或才能恢复出明文;
在计数器模式中,对计数器值加密后与明文异或产生密文,在解密时,只需要相同的计数器加密值与密文异或就可得到明文。
Chapter7 问题
7.4
a.
不会, P 3 只受 C 2 和 C 3 的影响 不会,P_3只受C_2和C_3的影响 不会,P3只受C2和C3的影响
b.
明文有一组中有错,会使后续密文组都受影响
接收者解密后的结果,除原有误的一组外,明文都可正确恢复。
7.5
在CBC模式中:
加密过程不能并行,加密的过程需要上一次加密的结果与明文进行异或;
解密过程可以并行,解密的过程中的密文块都可直接使用
7.7
zeropadding填充方式,它是使用0x00作为填充数据的填充方式,也就是说在分组时,最后一组明文的长度没有达到分组长度,那么就用0x00来补充。注意如果刚开始已经完整分组了也需要补一整个分组的0x00,否则无法解密
7.8
该错误将传播到的后面的
64
+
8
−
1
8
=
8
个单元
\frac{64+8-1}{8} = 8个单元
864+8−1=8个单元
共9个单元解密得到错误的明文。
Chapter 8 思考题
8.1 统计随机性和不可预测性有何区别?
统计随机性数列出现随机现象并通过某些统计测试
不可预测性是指序列生成方法的知识不足以确定数字或字母的序列
8.2 列出流密码的重要设计注意事项
1、加密序列的周期要长,若出现重复的周期过短,容易被破解
2、密钥流应该尽可能地接近真正随机数流的特征
3、密钥长度要长,避免暴力破解
8.3 为何不希望重用流密码的密钥?
分组密码的优点之一是可以重用密钥。
相比之下,如果两个明文是用流密码以相同的密钥加密的,那么密码分析会变得非常简单。
如果异或这两个密文流,那么结果就是原始明文的异或值。
如果明文是文本字符串、信用卡号或一些已知属性的字节流,那么就能成功地进行密码分析。
8.4 RC4中使用了哪些本原操作?
异或运算、取模运算、字节交换
Chapter8 问题
Programming :Implement the RC4 cipher, with your favorite programming language.
(1)Show me the source codes, and (2)Run your code , then present the result proving your work with screenshots.
参考链接:https://blog.csdn.net/u011377996/article/details/85221508
# -*- coding: utf-8 -*-
import base64
def get_message():
print("输入你的信息:")
s = input()
return s
def get_key():
print("输入你的秘钥:")
key = input()
if key == '':
key = 'none_public_key'
return key
def init_box(key):
"""
S盒
"""
s_box = list(range(256))
j = 0
for i in range(256):
j = (j + s_box[i] + ord(key[i % len(key)])) % 256
s_box[i], s_box[j] = s_box[j], s_box[i]
#print(type(s_box)) #for_test
return s_box
def ex_encrypt(plain,box,mode):
if mode == '2':
while True:
c_mode = input("选择解密模式:Base64 or ordinary\n")
if c_mode == 'Base64':
plain = base64.b64decode(plain)
plain = bytes.decode(plain)
break
elif c_mode == 'ordinary':
plain = plain
break
else:
print("Something Wrong,请重新新输入")
continue
res = []
i = j =0
for s in plain:
i = (i + 1) %256
j = (j + box[i]) %256
box[i], box[j] = box[j], box[i]
t = (box[i] + box[j])% 256
k = box[t]
res.append(chr(ord(s)^k))
cipher = "".join(res)
#print(cipher)
if mode == '1':
# 化成可视字符需要编码
print("加密后的输出:")
print(cipher)
# base64的目的也是为了变成可见字符
print("base64后的编码:")
print(str(base64.b64encode(cipher.encode('utf-8')),'utf-8'))
print("--------------加密完成------------")
if mode == '2':
print("解密后的密文:")
print(cipher)
print("--------------解密完成------------")
def get_mode():
print("请选择加解密模式")
print("1. 加密")
print("2. 解密")
mode = input()
if mode == '1':
message = get_message()
key = get_key()
box = init_box(key)
ex_encrypt(message,box,mode)
elif mode == '2':
message = get_message()
key = get_key()
box = init_box(key)
ex_encrypt(message, box, mode)
else:
print("输入有误")
if __name__ == '__main__':
while True:
get_mode()