0%

序列密码又称流密码,原理是明文流和密钥流按顺序逐位异或运算,从而产出密文流,序列密码属于对合运算。

以下是典型的序列密码RC4的加解密算法实现。其中秘钥流产生算法由RSA和PRGA两个核心子算法组成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# coding:utf-8
# RC4 python实现代码
# 仅支持128位ASCII码字符文本加解密,要支持任意输入需要更换编码方式
# 秋风木叶 2019-3-27

from FrankTools import ItoB, XOR, StoB, BtoS, swap

def KeyGenerator(K, n):

# RSA(The Key-Scheduling Algorithm)
# 秘钥调度算法
S = [i for i in range(0, 256)]
R = []
for i in range(0,256):
R.append(ord(K[i % len(K)]))
j = 0
for i in range(0,256):
j = (j + S[i] + R[i]) % 256
S[i], S[j] = swap(S[i], S[j])
#print('随机化后的S {}'.format(S))

# PRGA(The Pseudo-Random Generating Algorithm)
# 伪随机子密码生成算法
i = 0
j = 0
K_list = []
while(n):
i = (i+1)%256
j = (j+S[i])%256
S[i],S[j] = swap(S[i],S[j])
t = (S[i]+S[j])%256
K_list.append(S[i])
# K_list存储生成的秘钥
n -= 1

# 秘钥转换为二进制序列
k=''
for i in K_list:
k += ItoB(i)
#print('秘钥序列为:{}'.format(BtoS(k)))
return k

def Encrypt(M, K):
M_list = StoB(M)
K_list = KeyGenerator(K, len(M))
#print('------------{0},{1}'.format(len(M_list),len(K_list)))
#print(M_list,K_list)
return XOR(M_list,K_list)

def Decrypt(C, K):
C_list = C
K_list = KeyGenerator(K, len(C)/8)
#print('----------------{0},{1}'.format(len(C_list),len(K_list)))
#print(C_list,K_list)
return BtoS(XOR(C_list, K_list))

if __name__=='__main__':
#print('\n>>>Test!')
M = 'MING CHEN WU DIAN FA DONG FAN GONG'
K = 'XING CHUI PING YE KUO YUE YONG DA JIANG LIU'
C = Encrypt(M, K)
M1 = Decrypt(C, K)
print('明文加密之后产生的密文是: {}'.format(C))
print('解密出的明文是: {}'.format(M1))

其中引用了FrankTools模块中的ItoB, XOR, StoB, BtoS, swap函数,FrankTools模块中将常用函数打包以便调用,展示如下:

阅读全文 »

最近在备考软考信息安全工程师,学习到密码学部分,为了记忆更加深刻,将已经掌握并且觉得比较有趣的密码算法用Python来实现,简单记录一下。

古典密码接触到置换密码、代替密码和代数密码三种,其中置换密码相对简单,靠眼睛就可以完成加解密,所以没有必要实现了,代替密码主要有加法密码、乘法密码和仿射密码,仿射密码研究的是Vigenre密码,该密码是16世纪法国密码学家Vigenre使用过的密码,代数密码研究的是Vernam密码,该密码是美国电话电报公司的Gillbert Vernam在1917年为电报通信设计的一种非常方便的密码(我最喜欢这组密码)。

加法密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# coding:utf-8
# 加法密码实现
# 当前仅支持大写字符串加解密
# 秋风木叶 2019-3-10

# 字符串转单字符列表,再转为数字序列便于计算
def stoc(str):
ch_list = []
for i in str:
ch_list.append(i)
return [ord(i)-65 for i in ch_list]

# Int to Chr
# 将数字序列还原成大写字母序列
def itoc(list_int):
A = [chr(i+65) for i in list_int]
ch = ""
for i in A:
ch += i
return ch

# 计算密文序列
def Encrypt(Message,k,n):
print('>>>使用加法密码算法进行加密(k={}, n={})'.format(k,n))
return itoc([i+k%n for i in stoc(Message)])

# 计算明文序列
def Decrypt(Ciphertext,k,n):
# 解密方式1:通过构建密码表进行查表解密
# 解密方式2:通过加密逆运算计算明文
DecryptionType = 2
if(DecryptionType == 1):
print('>>>构建密码表:')
A = [i for i in range(0,n)]
print('>>>明文字母表:{}'.format(itoc(A)))
B = Encrypt(itoc(A),k,n)
print('>>>密文字母表:{}'.format(B))
CiphertextTables = dict(zip(B,A))
print('>>>构建密码表进行查表解密')
return itoc([CiphertextTables[i] for i in Ciphertext])
else:
print('>>>通过加密逆运算进行解密(k的逆元为:{})'.format(-k))
return itoc([c-k+n %n for c in stoc(Ciphertext)])

if __name__=='__main__':
# 当前仅支持大写字母串
A = ('ABCDEF')
print('输入的明文字符串为:{}'.format(A))
B = Encrypt(A,7,26)
print('加密后的密文:{}'.format(B))
C = Decrypt(B,7,26)
print('解密后的明文:{}'.format(C))

以上代码的执行结果:

1
2
3
4
5
输入的明文字符串为:ABCDEF
>>>使用加法密码算法进行加密(k=7, n=26)
加密后的密文:HIJKLM
>>>通过加密逆运算进行解密(k的逆元为:-7)
解密后的明文:ABCDEF

加法密码比较简单,加解密过程既可以通过公式计算实现,也可以使用查表的方式获得,代码中解密过程就分别使用了加密逆运算和查表两种思路来实现。

阅读全文 »