小工具 - 简单的随机数生成工具

Posted by morouu on 2021-12-27
Estimated Reading Time 52 Minutes
Words 9.6k In Total
Viewed Times

开发 - 简单的随机数生成工具


- 结构 -

  • 前端界面:MDUI + jQuery

  • 后端处理:Apache + PHP

  • 随机生成:Python 3.6

网址:https://www.dmantick.tk/tools/

- 原理流程 -

- 密钥初始化 -

  • 密钥KEY1]:根据服务器当前内存使用率(精确至48位小数)、CPU数据的C64编码值的生成sha256值(结果取128bit);
  • [密钥KEY2]:获取当前时间戳与[密钥KEY1]的C64编码值的生成的sha256值(结果取128bit);
  • [不变密钥KEY]:16384位RSA中P和Q乘积生成的sha256值(结果取128bit);

使用者可以随时通过向服务器发送请求,来实时生成[密钥KEY1]以及[密钥KEY2]的值,不变密钥则由服务器秘密保存。

注:本文所有提到的C64并非CRC-64算法。


- 随机字节流生产操作 -

  • [第一步]:先生成2048位的RSA,取其两个质数 P 和 Q,以及乘积 N 值;
  • [第二步]:使用[密钥KEY2]作为AES128密钥,输入值为 P 的sha256值的base64编码,之后取AES128加密结果的128bit(奇数次加密取前128bit,偶数次加密为后128bit)与前 1 次加密时使用的密钥异或的结果作为当前加密密钥,加密所得的结果的sha256值的base64编码作为当前需要加密的值,一共轮代 5 次;
  • [第三步]:获取使用者发送请求的时间戳以及当前加密时的时间戳的base64编码,以[不变密钥KEY]进行AES128加密,之后取 Q 和 前 1 次加密使用的密钥异或的结果作为当前加密密钥,加密所得的结果的sha256值的base64编码作为当前需要加密的值,一共轮代 5 次;
  • [第四步]:将[第二步]和[第三步]所得的结果异或,然后将异或所得的结果的base64编码以 P 和 Q,进行RSA2048的加密;
  • [第五步]:将[第四步]所得的结果分别取前一半和后一半的sha256值,以及所得结果和 N 的或的sha256值,以[前一半的sha256值] + [所得结果和 N 的或的sha256值] + [后一半的sha256值] 组成结果作为随机字节流;

由于sha256所得的hash值有浮动,所得随机字节流结果于 95 ~ 96字节之间,也就是一次最多能生成 90+ 的任意随机字符。


- 原理图示 -

image-20200520154230399.png


- 生成随机字节流的各个算法代码实现 -

主要用到算法:C64|BASE64|AES128|RSA|SHA256

- C64 -

(这个是我基于BASE64编码算法简单写的一个转码算法= =,本初是为了隐藏WEB的反弹shell弹回来的IP和端口):

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
'''
@Description: C64
@Author: DQ
@LastEditors : DQ
@Date: 2020-05-03 13:09:11
@LastEditTime : 2020-05-18 10:33:59
'''

# 简单的变种base64算法
# 若需转码数据字节的2进制流为6的倍数,则比base64多长1位;其余情况,均比base64少1位
# 局限是转码最小单位为字节,小于1个字节的数据流得补0
# 简单的替换表,可以随意改变,其实也可以当成一个简单的密钥
C64_TABLE = [
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x20',
'\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x40', '\x41', '\x42', '\x43',
'\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x60', '\x61', '\x62', '\x63'
]


def encrypt( s: str ):
# 先将每个字节转换成8位的2进制模式
bits = "".join(bin(byte)[ 2: ].zfill(8) for byte in bytes(s.encode('gbk')))[ ::-1 ]
length = len(bits)


# 然后进行(所转换成2进制位数长度 - 1)的循环(1个字节=8长,循环 8 - 1 = 7 次)
for count in range(length - 1):
# 具体算法为:当前位置值 和 后 1 位值的异或(迭代进行)
# 比如 1011 那么步骤为
# 取[10]11,1 ^ 0 = 1 => 1011,
# 取1[01]1,0 ^ 1 = 1 => 1111,
# 取11[11],1 ^ 1 = 0 => 1101,
# 但这并非最终结果,仅是一个例子,结果会受到下一步操作的影响

bits = bits[ :count ] + str(int(bits[ count ]) ^ int(bits[ count + 1 ])) + bits[ count + 1: ]

# 每次异或完毕后,进行11次循环,每次循环步骤为
# 先右循环移1位,然后倒置

for i in range(11):
bits = (bits[ -1 ] + bits[ :-1 ])[ ::-1 ]

# 先取得到的2进制流的奇位和偶位
# 公式为:奇数位组成值的前一半长 + 偶数位组成值 ^ 奇数组成位值 + 奇数位组成值后一半长
left = ""
right = ""
for i in range(length):
if (not i % 2):
left += bits[ i ]
else:
right += bits[ i ]
data = right[ :len(right) // 2 ] + "".join(
str(int(byte1) ^ int(byte2)) for byte1, byte2 in zip(left, right)) + right[ len(right) // 2: ]

# 取得结果的2进制流模6值,若不足6位则补值6位,若正好为6位则多补6位
# 比如 24->30 32->36
data = data + "".join(str(byte % 2) for byte in range(6 - len(data) % 6))

# 根据替换表进行替换
result = "".join(C64_TABLE[ int(data[ i * 6:(i + 1) * 6 ], 2) ] for i in range(len(data) // 6))

return result


# 解码的话,倒回去即可
def decrypt( s: str ):
data = "".join(bin(C64_TABLE.index(font))[ 2: ].zfill(6) for font in s)
data = data[ :-(len(data) % 8) ]
data_len = len(data)

right = data[ :data_len // 4 ] + data[ -data_len // 4: ]
left = "".join(str(int(byte1) ^ int(byte2)) for byte1, byte2 in zip(data[ data_len // 4:data_len // 4 * 3 ], right))
bits = ""

for i in range(data_len):
if (not i % 2):
bits += left[ i // 2 ]
else:
bits += right[ i // 2 ]

for count in range(data_len - 1, 0, -1):
for i in range(11):
bits = bits[ ::-1 ]
bits = (bits[ 1: ] + bits[ 0 ])
bits = bits[ :count - 1 ] + str(int(bits[ count ]) ^ int(bits[ count - 1 ])) + bits[ count: ]
bits = bits[ ::-1 ]
result = "".join(chr(int(bits[ x * 8:(x + 1) * 8 ], 2)) for x in range(len(bits) // 8)).encode("latin1").decode(
'gbk')

return result


if __name__ == '__main__':
while True:
try:

en = encrypt(input("input:"))
print("Encrypt: ", en)

de = decrypt(en)
print("Decrypt:", de)
except KeyboardInterrupt:
break

- BASE64 -

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
'''
@Description: Base64
@Author: DQ
@LastEditors : DQ
@Date: 2020-01-04 14:55:52
@LastEditTime : 2020-01-04 22:05:46
'''

# base64编码表
base64_dict = { 0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J',
10: 'K', 11: 'L', 12: 'M', 13: 'N', 14: 'O', 15: 'P', 16: 'Q', 17: 'R', 18: 'S',
19: 'T', 20: 'U', 21: 'V', 22: 'W', 23: 'X', 24: 'Y', 25: 'Z', 26: 'a', 27: 'b',
28: 'c', 29: 'd', 30: 'e', 31: 'f', 32: 'g', 33: 'h', 34: 'i', 35: 'j', 36: 'k',
37: 'l', 38: 'm', 39: 'n', 40: 'o', 41: 'p', 42: 'q', 43: 'r', 44: 's', 45: 't',
46: 'u', 47: 'v', 48: 'w', 49: 'x', 50: 'y', 51: 'z', 52: '0', 53: '1', 54: '2',
55: '3', 56: '4', 57: '5', 58: '6', 59: '7', 60: '8', 61: '9', 62: '+', 63: '/' }

# base64编码逆表
base64_reverse_dict = { 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18,
'T': 19, 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25, 'a': 26, 'b': 27,
'c': 28, 'd': 29, 'e': 30, 'f': 31, 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36,
'l': 37, 'm': 38, 'n': 39, 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45,
'u': 46, 'v': 47, 'w': 48, 'x': 49, 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54,
'3': 55, '4': 56, '5': 57, '6': 58, '7': 59, '8': 60, '9': 61, '+': 62, '/': 63 }


# base64转码
def enb64( source, enbytes = True ):
try:
data = source.encode( ) # 预处理将传入值转为2进制流
except AttributeError:
data = source
length = len(data) # 获取需转码的值的总长度
end = length % 3 # 获取补位数
out = "" # 预设输出变量
equal = "" # 预设输出补位
if (end != 0): # 若补位数不为0则计算需要进行的补位各个量
tmp = ""
for _ in range(3 - end):
tmp += "\x00"
equal += "="
data += bytes(tmp.encode( )) # 进行补位(\x00)
length += 3 - end # 刷新补位后的总长度
for part in range(length // 3): # 以每3个字节为1组进行操作
bins = ""
for byte in range(3):
bins += "%08d" % int(bin(data[ part * 3 + byte ])[ 2: ]) # 将每3个字节分解成 3 * 8 共 24 个bit

for byte in range(4):
out += base64_dict[ int(bins[ byte * 6:(byte + 1) * 6 ], 2) ] # 从上边24个bit中每6个bit的数值索引base64编码
if (end != 0): # 若补位数不为0则在结果后边补上对应数量的"="
out = (out[ :(-1) * (3 - end) ] + equal)
if (enbytes): # 判断是否需要将结果转为2进制流
out = out.encode( )
return out # 输出结果


# base64解码
def deb64( source, debytes = True ):
try:
data = source.decode( ) # 预处理将传入值进行2进制流解码
except AttributeError:
data = source
length = len(data) # 计算总长
equaln = length % 4 # 若长度不正确自动补"="
for _ in range(equaln): # 补"="
data += "="
end = data.count("=") # 计算"="的数量
out = bytes( ) # 预设输出变量
data = data.replace("=", "A") # 将补位符"="转换成"A"(000000)以好做解码处理
for part in range(length // 4): # 以每4个字符1组进行解码
bins = ""
for each in range(4):
bins += "%06d" % int(
bin(base64_reverse_dict[ data[ part * 4 + each ] ])[ 2: ]) # 将组中每个字符经过base64编码逆表得到的数值重组回24bit

for each in range(3):
out += bytes(chr(int(bins[ each * 8:(each + 1) * 8 ], 2)).encode("latin1")) # 将得到的24bit重组回 3 * 8 模式的3个字节
if (end != 0): # 若存在补位则将后边补位的"\x00"去除
out = out[ :(-1) * end ]
if (not debytes): # 判断是否将二进制流结果解码
out = out.decode( )
return out # 输出结果

if __name__ == '__main__':
pass

- AES128 -

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
'''
@Description: AES128
@Author: DQ
@LastEditors : DQ
@Date: 2020-03-14 21:16:22
@LastEditTime : 2020-03-15 01:52:14
'''

import b64, re, functools


class AES_128(object):

def __init__( self ):

# 声明正S盒
self.S_box = [
[ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 ],
[ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 ],
[ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 ],
[ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 ],
[ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 ],
[ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf ],
[ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 ],
[ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 ],
[ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 ],
[ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb ],
[ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 ],
[ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 ],
[ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a ],
[ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e ],
[ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf ],
[ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]
]

# 声明S盒的逆
self.S_box_r = [
[ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb ],
[ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb ],
[ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e ],
[ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 ],
[ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 ],
[ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 ],
[ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 ],
[ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b ],
[ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 ],
[ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e ],
[ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b ],
[ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 ],
[ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f ],
[ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef ],
[ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 ],
[ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d ]
]

# 声明RC常量
self.RC = [ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 ]

# 声明列混淆矩阵常量
self.BOX = [
[ 0x02, 0x03, 0x01, 0x01 ],
[ 0x01, 0x02, 0x03, 0x01 ],
[ 0x01, 0x01, 0x02, 0x03 ],
[ 0x03, 0x01, 0x01, 0x02 ]
]

self.BOX_r = [
[ 0x0e, 0x0b, 0x0d, 0x09 ],
[ 0x09, 0x0e, 0x0b, 0x0d ],
[ 0x0d, 0x09, 0x0e, 0x0b ],
[ 0x0b, 0x0d, 0x09, 0x0e ]
]

# 声明主要变量
self.KEY, self.KEY_EXTEND = [ ], [ ]

# 矩阵行列倒置
def re_rc( self, box ):
return [ [ row[ i ] for row in box ] for i in range(len(box[ 0 ])) ]

# 矩阵内容16进制字符转10进制数字
def str2dec( self, box ):
for i in range(len(box)):
for j in range(len(box[ i ])):
box[ i ][ j ] = int(box[ i ][ j ], 16)
return box

# 列混淆元计算
def fun2( self, i ):
i <<= 1
if (i & 0x100 != 0):
i = (i & 0xff) ^ 0x1b
return i

# 获取扩展密钥矩阵
def get_extend( self, key, rc, count = 10 ):
W = [ ]
W_each_len = len(key)
for col in self.re_rc(key):
W.append("".join(hex(each)[ 2: ] for each in col).zfill(W_each_len * 2))

for i in range(W_each_len, (count + 1) * W_each_len):
if (i % W_each_len):
W.append(hex(int(W[ i - W_each_len ], 16) ^ int(W[ i - 1 ], 16))[ 2: ].zfill(W_each_len * 2))
else:
W_tmp = "".join(hex(self.S_box[ int(each[ 0 ], 16) ][ int(each[ 1 ], 16) ])[ 2: ].zfill(2) for each in
re.findall(r'\w{1,2}', W[ i - 1 ][ 2: ] + W[ i - 1 ][ :2 ]))
W.append(hex(
int(str(hex(int(W_tmp[ :2 ], 16) ^ rc[ i // W_each_len ]))[ 2: ].zfill(2) + W_tmp[ 2: ], 16) ^ int(
W[ i - W_each_len ],
16))[ 2: ].zfill(
W_each_len * 2))

return [ [ W[ W_each_len * i + j ] for j in range(W_each_len) ] for i in range(len(W) // W_each_len) ]

# 加密
def aes_encode( self, content, key, rc, box, count = 10 ):
key_re = self.re_rc(key) # 密钥矩阵倒置
content_re = self.re_rc(content) # 明文矩阵倒置
key_extend = self.get_extend(key, rc, count) # 获取密钥扩展矩阵集
aes_en = [ [ ] for i in range(len(key_re)) ] # 预设加密结果矩阵
aes_len = len(key_re) # 计算矩阵边长

# 首次轮密钥加
for i in range(aes_len):
for j in range(aes_len):
aes_en[ i ].append(hex(key_re[ i ][ j ] ^ content_re[ i ][ j ])[ 2: ].zfill(2))

# 进行共10轮操作
for this_round in range(count):

# 字节替代
for i in range(aes_len):
for j in range(aes_len):
aes_en[ i ][ j ] = hex(
self.S_box[ int(aes_en[ i ][ j ][ 0 ], 16) ][ int(aes_en[ i ][ j ][ 1 ], 16) ])[ 2: ].zfill(2)

# 行位移
aes_en = self.re_rc(aes_en)
for i in range(1, aes_len):
for j in range(i):
aes_en[ i ].append(aes_en[ i ].pop(0))
aes_en = self.re_rc(aes_en)

# 若不为最后一次加密则进行列混淆
if (this_round != 9):
for i in range(aes_len):
tmp_list = [ ]
for j in range(aes_len):
tmp_ = [ ]
for k in range(aes_len):
a = int(aes_en[ i ][ k ], 16)
b = bin(box[ j ][ k ])[ 2: ][ ::-1 ]
w = eval("^".join([ line for line in "^".join(
[ "self.fun2(" * (bit - 1) + "a" * (bit > 0) + ")" * (bit - 1) for bit in
[ pos * bool(int(b[ pos - 1 ])) for pos in range(1, len(b) + 1) ] ]).split('^') if
bool(line) ]))
tmp_.append(w)
tmp_list.append(hex(functools.reduce(lambda x, y: x ^ y, tmp_))[ 2: ].zfill(2))
aes_en[ i ] = tmp_list

# 轮密钥加
for i in range(aes_len):
tmp_list = re.findall(r'\w{1,2}', key_extend[ this_round + 1 ][ i ])
for j in range(aes_len):
aes_en[ i ][ j ] = hex(int(aes_en[ i ][ j ], 16) ^ int(tmp_list[ j ], 16))[ 2: ].zfill(2)

return self.re_rc(aes_en)

# 解密
def aes_decode( self, passwd, key, rc, box, count = 10 ):
passwd_re = self.re_rc(passwd) # 密文矩阵倒置
key_extend = self.get_extend(key, rc, count) # 获取密钥扩展矩阵集
aes_de = [ [ ] for i in range(len(key)) ] # 预设解密结果矩阵
aes_len = len(key) # 计算矩阵边长

# 首次轮密钥加
for i in range(aes_len):
for j in range(aes_len):
aes_de[ i ].append(
hex(int(key_extend[ count ][ i ][ j * 2:(j + 1) * 2 ], 16) ^ passwd_re[ i ][ j ])[ 2: ].zfill(
2))

# 进行共10轮操作
for this_round in range(count):

# 进行逆向行位移
aes_de = self.re_rc(aes_de)
for i in range(1, aes_len):
for j in range(i):
aes_de[ i ].insert(0, aes_de[ i ].pop( ))
aes_de = self.re_rc(aes_de)

# 进行逆向字节替代
for i in range(aes_len):
for j in range(aes_len):
aes_de[ i ][ j ] = hex(
self.S_box_r[ int(aes_de[ i ][ j ][ 0 ], 16) ][ int(aes_de[ i ][ j ][ 1 ], 16) ])[ 2: ].zfill(2)

# 进行路密钥加
for i in range(aes_len):
tmp_list = re.findall(r'\w{1,2}', key_extend[ count - this_round - 1 ][ i ])
for j in range(aes_len):
aes_de[ i ][ j ] = hex(int(aes_de[ i ][ j ], 16) ^ int(tmp_list[ j ], 16))[ 2: ].zfill(2)

# 进行逆向列混淆
if (this_round != 9):
for i in range(aes_len):
tmp_list = [ ]
for j in range(aes_len):
tmp_ = [ ]
for k in range(aes_len):
a = int(aes_de[ i ][ k ], 16)
b = bin(box[ j ][ k ])[ 2: ][ ::-1 ]
w = eval("^".join([ line for line in "^".join(
[ "self.fun2(" * (bit - 1) + "a" * (bit > 0) + ")" * (bit - 1) for bit in
[ pos * bool(int(b[ pos - 1 ])) for pos in range(1, len(b) + 1) ] ]).split('^') if
bool(line) ]))
tmp_.append(w)
tmp_list.append(hex(functools.reduce(lambda x, y: x ^ y, tmp_))[ 2: ].zfill(2))
aes_de[ i ] = tmp_list

return self.re_rc(aes_de)

def init( self, key, count = 10 ):
self.KEY = key
self.KEY_EXTEND = self.get_extend(key = key, rc = self.RC, count = count)


def str2box( s, r = 4, l = 4, byte = 2 ):
box = [ [ ] for i in range(r) ]
for i in range(r):
for j in range(l):
box[ i ].append(int(s[ (i * r + j) * byte:((i * r + j) + 1) * byte ], 16))
return box


def box2str( box ):
result = ""
for row in range(len(box)):
for each in box[ row ]:
result += each
return result

# AES128加密
def aes128_encode( content, aes, bit = 32, pad = '\n' ):
s_hex_base64 = "".join([ "%2x" % ord(each) for each in b64.enb64(source = content, enbytes = False) ])
s_hex_base64_plus = s_hex_base64 + "0" * (len(s_hex_base64) % bit) if len(
s_hex_base64) > bit else s_hex_base64 + "0" * (bit - len(s_hex_base64))
return pad.join(box2str(aes.aes_encode(
content = aes.re_rc(str2box(s = s_hex_base64_plus[ index * bit:(index + 1) * bit ], r = 4, l = 4, byte = 2)),
key = aes.KEY, rc = aes.RC, box = aes.BOX)) for index in range(len(s_hex_base64_plus) // bit))

# AES128解密
def aes128_decode( passwd, aes, bit = 32, pad = '\n' ):
result = "".join(box2str(
aes.re_rc(aes.aes_decode(passwd = str2box(s = line, r = 4, l = 4, byte = 2), key = aes.KEY, rc = aes.RC,
box = aes.BOX_r))) for line in passwd.split(pad))
return b64.deb64(
"".join(chr(int(result[ i * 2:(i + 1) * 2 ], 16)) for i in range(len(result) // 2)).replace("\x00", ""),
debytes = False)

# 显示密钥矩阵
def show_decbox( box ):
for row in range(len(box)):
print("[ " + " , ".join("0x" + hex(each)[ 2: ].zfill(2) for each in box[ row ]) + " ]")
print("\n")

# 显示密钥扩展矩阵
def show_key_extend_box( box ):
for row in range(len(box)):
print("*" * 24 + "[ _ROUND_<%02d> ]" % row + "*" * 24)
for i in range(len(box[ row ])):
print("[ " + " , ".join(
"0x" + box[ row ][ j ][ i * 2:(i + 1) * 2 ].zfill(2) for j in range(len(box[ row ][ i ]) // 2)) + " ]")
print("*" * 24 + "[ _END_ROUND_ ]" + "*" * 24 + "\n\n")


def hex2str( s ):
return "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', s)).encode('latin1')


if __name__ == '__main__':

# 密钥矩阵
key = [
[ 0x12, 0x34, 0x56, 0x78 ],
[ 0x78, 0x65, 0x43, 0x21 ],
[ 0x23, 0x33, 0x33, 0x33 ],
[ 0x33, 0x33, 0x33, 0x32 ]
]

aes = AES_128( )
aes.init(key = key, count = 10)
pad = "\n"

print("*" * 52 + "[ AES128 ]" + "*" * 52)
print("密钥矩阵 => ")
show_decbox(aes.KEY)
print("密钥扩展矩阵 => ")
show_key_extend_box(aes.KEY_EXTEND)
print("*" * 52 + "[ AES128 ]" + "*" * 52)

while True:
try:
c = aes128_encode(content = input("请输入需要加密的信息:"), aes = aes, bit = 32, pad = pad)
print("[ 密文 =》]")
print(c)
print("[ 密文流 =》]")
print(hex2str(c.replace(pad, "")))
s = aes128_decode(passwd = c, aes = aes, bit = 32, pad = pad)
print("[ 明文 =》]")
print(s)
except KeyboardInterrupt:
print("Bye!")
exit(0)

- RSA -

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
'''
@Description: RSA
@Author: DQ
@LastEditors : DQ
@Date: 2020-01-04 20:26:19
@LastEditTime : 2020-03-15 03:03:20
'''

import random, b64, re, math


class RSA_value(object):
def __init__( self ):
# 声明主要变量
self.P, self.Q, self.N, self.Y, self.E, self.D = 0, 0, 0, 0, 0, 0

# 声明小质数表
self.small_primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,
131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191,
193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421,
431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499,
503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593,
599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659,
661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013,
1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069,
1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291,
1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583,
1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657,
1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889,
1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987,
1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213,
2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,
2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531,
2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617,
2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819,
2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903,
2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181,
3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,
3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511,
3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571,
3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821,
3823, 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907,
3911, 3917, 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, 4133, 4139,
4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231,
4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, 4483, 4493,
4507, 4513, 4517, 4519, 4523, 4547, 4549, 4561, 4567, 4583,
4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831,
4861, 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937,
4943, 4951, 4957, 4967, 4969, 4973, 4987, 4993, 4999, 5003,
5009, 5011, 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,

5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, 5171, 5179,
5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387,
5393, 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,

5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, 5519, 5521,
5527, 5531, 5557, 5563, 5569, 5573, 5581, 5591, 5623, 5639,
5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683, 5689, 5693,
5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,

5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857,
5861, 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939,
5953, 5981, 5987, 6007, 6011, 6029, 6037, 6043, 6047, 6053,
6067, 6073, 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,

6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, 6217, 6221,
6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301,
6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367,
6373, 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,

6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, 6569, 6571,
6577, 6581, 6599, 6607, 6619, 6637, 6653, 6659, 6661, 6673,
6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733, 6737, 6761,
6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,

6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917,
6947, 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997,
7001, 7013, 7019, 7027, 7039, 7043, 7057, 7069, 7079, 7103,
7109, 7121, 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,

7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, 7283, 7297,
7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411,
7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499,
7507, 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,

7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, 7639, 7643,
7649, 7669, 7673, 7681, 7687, 7691, 7699, 7703, 7717, 7723,
7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817, 7823, 7829,
7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,

7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017,
8039, 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111,
8117, 8123, 8147, 8161, 8167, 8171, 8179, 8191, 8209, 8219,
8221, 8231, 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,

8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, 8377, 8387,
8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501,
8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597,
8599, 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,

8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, 8737, 8741,
8747, 8753, 8761, 8779, 8783, 8803, 8807, 8819, 8821, 8831,
8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893, 8923, 8929,
8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,

9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109,
9127, 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199,
9203, 9209, 9221, 9227, 9239, 9241, 9257, 9277, 9281, 9283,
9293, 9311, 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,

9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, 9437, 9439,
9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533,
9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631,
9643, 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,

9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, 9803, 9811,
9817, 9829, 9833, 9839, 9851, 9857, 9859, 9871, 9883, 9887,
9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967, 9973 ]

# 递归求逆元
def gcd( self, a, b ): # 扩展欧几里算法优化版
if (b == 0):
return 1, 0
else:
x0, y0 = self.gcd(b, a % b) # 递归计算a*x0 + b*y0=1(a与b互质)中的x0与y0值
return y0, x0 - a // b * y0

# 快速幂模算法
def mod_quick( self, a, b, c ): # a b c依次为基数 幂数 以及 模数
array = bin(b)[ 2: ][ ::-1 ] # 取幂数的二进制,并将其倒叙(从左到右→从小到大)
n = len(array) # 获取二进制数位数(也就是b的bits)
result = 1 # 初始化结果
if (array[ 0 ] == '1'): # 这里以字符串的思想去判断,规避了int()的时间,若 b 的二进制首位为 1,将 a 填入列表
result = a

for _ in range(1, n): # 循环遍历 b 的所有二进制位数
next = (a * a) % c # 循环幂模运算
if (array[ _ ] == '1'): # 若 b 的该二进制位值为 1,则进行计算
result = (result * next) % c
a = next # a 重定向幂模结果
result %= c
return result # 返回结果

# 判断大质数(拉宾米勒素性判断)
def bool_p( self, N, X = 5 ):
M = (N - 1) // 2 # N=(2**r)*M+1的反算
r = 1
while (not M % 2): # 保证取到奇数M
M //= 2
r += 1
for _ in range(X):
A = random.randint(2, N - 1) # 取随机数A
get = self.mod_quick(A, M, N) # 第四步测试 A**M%N==1则算通过1次测试
if (get != 1): # 此时get=(A**M)%N
i = 0 # 进行第三步测试 A**((2**i)*M)%N=N-1 i<r
while (get != N - 1):
if (i >= r - 1): # 若i>=r则不通过
return False
else:
i += 1
get = (get * get) % N # get=(A**(M*2**i))%N
return True

# 大质数生成(取P或Q的值)
def get_p( self, size = 1024, seed = 0 ):
random.seed = seed # 设置随机种子保证取值广泛性
while True:
bool = False
n = random.randint(2 ** (size - 2), 2 ** (size - 1)) * 2 + 1 # 保证奇数
if (n % 6 != 5 and n % 6 != 1): # 6左右判断法,大于4的素数必然是6的倍数-1或+1
continue
for _ in self.small_primes: # 模小质数表判断
if (not n % _): # 若能模进则不为质数
bool = True
break
if (not bool):
if (self.bool_p(n)): # 进行拉宾米勒的素性判断
return n

def q( self, size = 1024, seed = 0 ):
return self.get_p(size = size, seed = seed)

def p( self, size = 1024, seed = 0 ):
return self.get_p(size = size, seed = seed)

# 求E值与D值
def e_d( self, N, size = 16, seed = 0 ):
if (N != 0):
random.seed = (seed) # 设置随机种子
while True:
e = self.get_p(size = size) # 生成指定位的质数E,直至能够满足要求为止
d = self.gcd(e, N)[ 0 ]
if (d < 0): # 若E与M(P-1)*(Q-1)组合不存在正确的D值则继续生成E
continue
else:
return e, d # 若存在正确的D值则返回E值和D值
else:
return 0

def init( self, size = 2048, seed = 0 ):
self.P = self.p(size = size // 2, seed = seed)
self.Q = self.q(size = size // 2, seed = seed)
self.N = self.P * self.Q
self.Y = (self.P - 1) * (self.Q - 1)
self.E, self.D = self.e_d(N = self.Y)


# 加密
def rsa_encode( content, rsa, pad = '\n' ):
s_hex_base64 = "".join([ "%2x" % ord(each) for each in b64.enb64(source = content, enbytes = False) ])
rsa_hex_len = len(hex(rsa.N)[ 2: ]) - 1
return pad.join(
hex(rsa.mod_quick(int(s_hex_base64[ line * rsa_hex_len:(line + 1) * rsa_hex_len ], 16), rsa.E, rsa.N))[ 2: ] for
line in range(math.ceil(len(s_hex_base64) / rsa_hex_len)))


# 解密
def rsa_decode( pass_v, rsa, pad = '\n' ):
return b64.deb64("".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', "".join(
hex(rsa.mod_quick(int(line, 16), rsa.D, rsa.N))[ 2: ] for line in pass_v.split(pad)))), debytes = False)


def hex2str( s ):
return "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', s)).encode('latin1')

def hex2str_crypt( s ,pad = '\n'):
return[ "".join(chr(int(each, 16)) for each in re.findall(r'\w{1,2}', part)).encode('latin1') for part in [line for line in s.split(pad)] ]

if __name__ == '__main__':
rsa = RSA_value( )
rsa.init(size = 16384)
pad="\n"
print("*" * 24 + "[ RSA ]" + "*" * 24)
print("P => : ", hex2str(hex(rsa.P)[ 2: ]))
print("Q => : ", hex2str(hex(rsa.Q)[ 2: ]))
print("N => : ", hex2str(hex(rsa.N)[ 2: ]))
print("E => : ", hex2str(hex(rsa.E)[ 2: ]))
print("D => : ", hex2str(hex(rsa.D)[ 2: ]))
print("*" * 24 + "[ RSA ]" + "*" * 24)
while True:
try:
c = rsa_encode(content = input("请输入需要加密的信息:"), rsa = rsa,pad = pad)
print("*" * 24 + "[ 密文 =》 ]" + "*" * 24)
print("HEX => ","0x"+c)
print("DEC => ",int(c,16))
print("OCT => ",oct(int(c,16)))
print("BIN => ",bin(int(c,16)))
print("*" * 24 + "[ 密文流 =》]" + "*" * 24)
print(hex2str_crypt(s = c, pad = pad))
s = rsa_decode(pass_v = c, rsa = rsa, pad = pad)
print("*" * 24 + "[ 明文 =》]" + "*" * 24)
print(s)
except KeyboardInterrupt:
print("Bye!")
exit(0)

- SHA256 -

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
'''
@Description: SHA256
@Author: DQ
@LastEditors : DQ
@Date: 2020-03-14 19:11:23
@LastEditTime : 2020-03-15 05:10:59
'''

import re, functools


class SHA_256(object):
def __init__( self ):

# 初始化哈希初值
self.Hash_init = [
0x6a09e667, 0xbb67ae85,
0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c,
0x1f83d9ab, 0x5be0cd19
]

# 初始化哈希常量
self.Hash_const = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
]

# 右旋转
def rightrotate_( self, s, length ):
return s[ -length: ] + s[ :-length ]

# 右移位
def rightshift_( self, s, length ):
return "0" * length + s[ :-length ]

# hash加
def hash_add( self, x, y ):
return (x + y) & 0xffffffff

# 扩充内容
def prepare_( self, data ):
try:
data = data.encode( )
except AttributeError:
data = data
data_bin_steam = "".join(bin(each)[ 2: ].zfill(8) for each in data)
data_bin_len = len(data_bin_steam)
data_append = ((448 - (data_bin_len % 512)) if (data_bin_len % 512) < 448 else (448 + 512 - (data_bin_len % 512))) - 1

return data_bin_steam + "1" + "0" * data_append + bin(
data_bin_len)[ 2: ].zfill(64)

# hash256
def main_( self, data ):
data_blocks = [ data[ index*512:(index + 1) * 512 ] for index in range(len(data) // 512) ]
data_hash_main = self.Hash_init.copy( )


# 对每个块进行摘要
for block in data_blocks:

# 求W[0~15]
W = re.findall('\d{32}', block[ :32 * 16 ])

# 求W[16~63]
for i in range(16, 64):
o0 = int(self.rightrotate_(W[ i - 15 ], 7), 2) ^ \
int(self.rightrotate_(W[ i - 15 ], 18), 2) ^ \
int(self.rightshift_(W[ i - 15 ], 3), 2)

o1 = int(self.rightrotate_(W[ i - 2 ], 17), 2) ^ \
int(self.rightrotate_(W[ i - 2 ], 19), 2) ^ \
int(self.rightshift_(W[ i - 2 ], 10), 2)
W.append(bin(functools.reduce(self.hash_add, [ int(W[ i - 16 ], 2), o0, int(W[ i - 7 ], 2), o1 ]))[2: ].zfill(32))

data_hash = data_hash_main.copy( )

# 进行64轮摘要
for i in range(64):
s0 = int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 2), 2) ^ \
int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 13), 2) ^ \
int(self.rightrotate_(bin(data_hash[ 0 ])[ 2: ].zfill(32), 22), 2)

maj = (data_hash[ 0 ] & data_hash[ 1 ]) ^ \
(data_hash[ 0 ] & data_hash[ 2 ]) ^ \
(data_hash[ 1 ] & data_hash[ 2 ])

s1 = int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 6), 2) ^ \
int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 11), 2) ^ \
int(self.rightrotate_(bin(data_hash[ 4 ])[ 2: ].zfill(32), 25), 2)

ch = (data_hash[ 4 ] & data_hash[ 5 ]) ^ ((~data_hash[ 4 ]) & data_hash[ 6 ])

t1 = functools.reduce(self.hash_add,[ data_hash[ 7 ], s1, ch, self.Hash_const[ i ] + int(W[ i ], 2)])
t2 = functools.reduce(self.hash_add, [ s0, maj ])

data_hash=[ self.hash_add(data_hash[i - 1] ,t1*(not i%4 )) for i in range(1,8)]
data_hash.insert(0, self.hash_add(t1,t2))

#print("<%d>[ "%i+" , ".join(hex(each) for each in data_hash)+"]")

data_hash_main = [ self.hash_add(data_hash[ i ],data_hash_main[ i ]) for i in range(8) ]
return "".join(hex(each)[ 2: ].zfill(2) for each in data_hash_main)


def show_decbox( box , length):
for row in range(len(box) // length):
print("[ " + " , ".join("0x" + hex(each)[ 2: ].zfill(8) for each in [box[row*length + i] for i in range(length)]) + " ]")
print("\n")


if __name__ == '__main__':
sha256=SHA_256()

print("*" * 52 + "[ SHA256 ]" + "*" * 52)
print("哈希初值 => ")
show_decbox(sha256.Hash_init,2)
print("哈希常量 => ")
show_decbox(sha256.Hash_const, 8)
print("*" * 52 + "[ SHA256 ]" + "*" * 52)

while True:
try:
c = sha256.main_(data = sha256.prepare_(data = input("请输入需要进行SHA256的值:")))
print("[ SHA256 =》]")
print(c)
except KeyboardInterrupt:
print("Bye!")
exit(0)


- 生成随机字节流的处理代码实现 -

生成[密钥KEY1]以及[密钥KEY2] :

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
import time,psutil,c64,sha256

def get_handware_data():
# 获取当前内存数据
memory_data = psutil.virtual_memory()
# 求当前内存使用率(结果精确至小数点后48位)
memory_use = str("%.48f"%(memory_data.used / memory_data.total))
# 获取当前CPU数据
cpu_info = psutil.cpu_times()
cpu_status = "|".join(str(each) for each in (cpu_info.user,cpu_info.nice,cpu_info.system))
return cpu_status + "|" + memory_use

def get_key_1(s:str):
# 生成[密钥KEY1]
SHA256 = sha256.SHA_256()
return SHA256.main_(SHA256.prepare_(c64.encrypt(s)))[:32]

def get_key_2(s:str):
# 通过[密钥KEY1]来生成[密钥KEY2]
SHA256 = sha256.SHA_256()
return SHA256.main_(SHA256.prepare_(c64.encrypt(str(time.time()).replace('.','')+s)))[:32]

def get_key():
# 获取生成的两个密钥
key1 = get_key_1(get_handware_data())
key2 = get_key_2(key1)
return key1,key2

if __name__ == '__main__':
key1,key2 = get_key()
print(key1)
print(key2)

生成随机字节流:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import rsa,sha256,aes128,sys,time

def get_rsa_data():

# 获取RSA数据

RSA = rsa.RSA_value()
RSA.init(2048)
return RSA

def get_aes128_box(box:list):

# AES128密钥矩阵转换单行数据

return [[box[i*4+j] for j in range(4)] for i in range(4)]

def get_aes128_box_r(box:list):

# 单行数据转换AES128密钥矩阵

temp_list=[]
for i in range(4):
for j in range(4):
temp_list.append(box[i][j])
return temp_list

def get_rand_1(key2:str,p:str,count:int = 5):

# [第二步] 的操作

AES = aes128.AES_128()
SHA256 = sha256.SHA_256()
aes_key = get_aes128_box([int(key2[i*2:(i+1)*2],16) for i in range(len(key2)//2)])

result = SHA256.main_(SHA256.prepare_(p))

for i in range(count):
AES.init(aes_key,10)
AES_c = aes128.aes128_encode(result,AES,32,'')
if(count != 4):
if(not i%2):
aes_get = AES_c[-32:]
else:
aes_get = AES_c[32:]
aes_key = get_aes128_box([a ^ b for a,b in zip(get_aes128_box_r(aes_key),[int(aes_get[j*2:(j+1)*2],16) for j in range(len(aes_get)//2)])])
result = SHA256.main_(SHA256.prepare_(AES_c))
else:
result = AES_c

return result

def get_rand_2(request_time:str,mainkey:str,q:str,count:int = 5):

# [第三步] 的操作

AES = aes128.AES_128()
SHA256 = sha256.SHA_256()
aes_key = get_aes128_box([int(mainkey[i*2:(i+1)*2],16) for i in range(len(mainkey)//2)])
aes_q_key =[int(q[i*2:(i+1)*2],16) for i in range(len(q[:32])//2)]
timestamp = str(time.time()).replace('.','')
result = request_time + timestamp

for i in range(count):
AES.init(aes_key,10)
AES_c = aes128.aes128_encode(result,AES,32,'')
if(i != 4):
aes_key = get_aes128_box([a ^ b for a,b in zip(get_aes128_box_r(aes_key),aes_q_key)])
result = SHA256.main_(SHA256.prepare_(AES_c))
else:
result = AES_c

return result

def get_rand_3(rand1:str,rand2:str,RSA):

# [第四步] 的操作

rand1_xor_rand2 = "".join(chr(ord(a) ^ ord(b)) for a,b in zip(rand1,rand2))
RSA_c = rsa.rsa_encode(rand1_xor_rand2,RSA,'')
return RSA_c

def get_result(s:str,n:str):

# [第五步] 的操作

SHA256 = sha256.SHA_256()
s_or_n = "".join(chr(ord(a) | ord(b)) for a,b in zip(s,n))
left = SHA256.main_(SHA256.prepare_(s[:len(s)//2]))
right = SHA256.main_(SHA256.prepare_(s[-len(s)//2:]))
result = left + SHA256.main_(SHA256.prepare_(s_or_n)) + right

return result

def get_random(key2:str,mainkey:str,request_time:str):

# [第一步]
RSA = get_rsa_data()

# [第二步]
rand1 = get_rand_1(key2,hex(RSA.P)[2:],5)

# [第三步]
rand2 = get_rand_2(request_time,mainkey,hex(RSA.Q)[2:],5)

# [第四步]
rand3 = get_rand_3(rand1,rand2,RSA)

# [第五步]
result = get_result(rand3,hex(RSA.N)[2:])

return result

if __name__ == '__main__':
if(len(sys.argv) == 4):
print(get_random(sys.argv[1],sys.argv[2],sys.argv[3]))
else:
exit(0)

- 后端代码实现 -

main.php:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
<?php
session_start();

class Rand_config{

# 操作选项
private $setting = ['get_rand_key','refresh_rand_key','get_rand_result','refresh_rand_result'];

# 调用Python的结果
private $cmd_result;

# 存储在服务器的 [不变密钥KEY]
private $private_key = '43fada45363a416167d4b3dadc2f7b49';

private $result = '';
private $status = '';
private $error = '';

private function exec_cmd($cmd){
# 调用Python
exec($cmd,$this->cmd_result);
$this->result = count($this->cmd_result) > 0 ? implode('|',$this->cmd_result) : $this->result = '出错了!';
}


public function __construct($type = null){
try{

if(!is_null($type)){

if(in_array($type,$this->setting,true)){

# 获取当前操作的索引值
$index = array_search($type,$this->setting);

switch ($index){

# 获取[密钥KEY1]以及[密钥KEY2]的调用Python操作
case 0:
# 设置Python处理时间
$_SESSION['endtime_key'] = time() + .5;
# 调用Python进行处理
$this->exec_cmd('python3 /app/a.py');
if($this->result != '出错了!'){

# 若处理成功则获得[密钥KEY1]和[密钥KEY2]
$_SESSION['key'] = $this->result;
$this->status = "exec";
}else{
$this->status = "failed";
}
break;

# 获取[密钥KEY1]以及[密钥KEY2]的刷新操作
case 1:
if(isset($_SESSION['endtime_key']) and $_SESSION['endtime_key'] <= time()){

# 若处理完成且获取成功,则返回OK
$this->status = 'OK';
}
break;

# 获取随机字符的一系列操作
case 2:
if(isset($_POST['request_time']) and isset($_SESSION['key']) and isset($_POST['fonts']) and isset($_POST['url_decode']) and isset($_POST['len'])){

# 设置Python处理时间
$_SESSION['endtime_result'] = time() + 2;
# 获取当前的[密钥KEY1]和[密钥KEY2]
$keys = explode('|',$_SESSION['key']);

# 使用者是否要求对其他字符预先进行URL解码
$fonts = $_POST['url_decode'] === 'true' ? urldecode($_POST['fonts']) : $_POST['fonts'];

# 将使用者选定的随机字符列表添加入数组,并去重
$result_array = preg_split('//', $fonts, -1, PREG_SPLIT_NO_EMPTY);
array_unique($result_array);
$len = count($result_array);

# 获取使用者要求的随机字符长度(字节数)
$rand_len = ($_POST['len'] > 90 or $_POST['len'] <= 0) ? 45 : $_POST['len'];

if(count($keys) === 2){

# 若一切无误则调用Python生成随机字节流
$this->exec_cmd("python3 /app/b.py ".join(' ',[$keys[0],$keys[1],intval($_POST['request_time']])));
if($this->result != '出错了!'){

# 获取生成的随机字节流并逐个字节添加入数组
$_SESSION['rand'] = $this->result;
$contents = '';
preg_match_all('/[\S\s]{2}/i',$_SESSION['rand'],$bytes,2);

# 使用生成的随机字节流生成随机字符
for($i = 0;$i < $rand_len;$i++){ $contents .= $result_array[hexdec($bytes[$i][0]) % $len];}
$_SESSION['rand_str'] = $contents;
$this->status = 'exec';

}else{

$this->status = 'failed';
}
}else{

$this->status = 'failed';
}
}else{

$this->status = 'failed';
}
break;

# 获取随机字符的刷新操作
case 3:
if(isset($_SESSION['endtime_result']) and $_SESSION['endtime_result'] <= time()){

# 若处理完成且获取成功,则返回OK
$this->status = 'OK';
}
break;
}
}
}

}catch(Exception $e){

$this->error = $e->getMessage()."\x0a".'出错了!';
}
}

public function __toString(){

return $this->error === '' ? (string)$this->status : (string)$this->error;
}
}

# 将操作得到的结果以JSON方式返回,方便前端的jQuery处理
function json_result($type,$status,$contents = ''){
header("Content-Type: text/json");
echo json_encode(array(
'type'=>$type,
'status'=>$status,
'result'=>base64_encode($contents)
));
}


# 请求传入的入口
# 对传入的请求判断并进行对应的操作
if(isset($_POST['action'])){

$status = (string) new Rand_config($_POST['action']);

if($status === 'OK'){
if($_POST['action'] === 'refresh_rand_key'){

json_result($_POST['action'],$status,$_SESSION['key']);

}else if($_POST['action'] === 'refresh_rand_result'){

json_result($_POST['action'],$status,$_SESSION['rand_str']);

}
}else{
json_result($_POST['action'],$status);
}


}


?>


- 效果演示 -

主界面:

image-20200520144239928.png

随意生成一个长度为 60的随机字符:

image-20200520144606393.png

再使用[将其他字符URL解码]功能,生成包含扩展ascii的内容:

image-20200520144417007.png

由于html可能无法正确解析一些扩展ascii码的内容,实际上在index.php的返回的JSON数据流是使用了BASE64将随机字符预先编码的,因而可以直接将JSON中的BASE64解码即可得到一些html无法正常显示的随机字符:

image-20200520145038721.png

以及:

image-20200520145309953.png


*最后关于中文的问题,由于这个随机原理是以单字节为基本单位操作,而中文是由多字节组成,所以无法支持随机中文字符(不过如果将加解密的中文统一规范化编码倒是可以的)。


如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。也欢迎您共享此博客,以便更多人可以参与。如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。谢谢 !