├── 1数字图像的处理.py ├── 2组内加密.py ├── 3分组运行模式.py ├── 4密文图像显示.py ├── 5密文图像解密.py ├── 6三重DES和CBC分组加密实现.py ├── README.md ├── decrypted_img.png ├── encrypt_data.txt ├── encrypted_img.png ├── group_data.txt ├── iv.txt ├── keys.txt ├── original_img.png └── 说明.txt /1数字图像的处理.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 1数字图像处理 5 | 说明:本代码旨在提取图片中的像素点,将每个像素点的RGB值转换为 6 | 二进制的01比特序列,再将得到的比特序列按照DES明文分组要求进行 7 | 64比特的明文分组,采用了PKCS#5填充标准进行填充,最终得到分组 8 | 的list列表 9 | ''' 10 | from PIL import Image 11 | 12 | #图片像素二进制值获取函数 13 | def get_pixel(img): 14 | im = Image.open(img) 15 | rgb_im = im.convert('RGB') 16 | img_width=im.size[0] #获取图像的宽 17 | img_height=im.size[1] #获取图像的高 18 | bin_data='' 19 | for i in range(img_width): #遍历每一个像素点 20 | for j in range(img_height): 21 | r, g, b = rgb_im.getpixel((i, j)) #获取像素点的rgb值 22 | # print(r, g, b) 23 | bin_data+='{:08b}'.format(r) 24 | bin_data+='{:08b}'.format(g) 25 | bin_data+='{:08b}'.format(b) 26 | return bin_data,img_width,img_height 27 | 28 | #DES明文分组处理函数 29 | def set_group(bin_data): 30 | print("*** 正在进行明文分组 ***") 31 | bin_data_list=[] 32 | data_length=len(bin_data) 33 | i=0 34 | while data_length>=64: #按照 35 | #print("正在划分第"+str(i)+"个明文分组 ",data_length) 36 | bin_data_list.append(bin_data[:64]) 37 | data_length-=64 38 | bin_data=bin_data[64:] 39 | i+=1 40 | print("正在处理最后一个明文分组 ",data_length) 41 | if data_length == 0: #若恰好能够完全分组 填充一定要进行,填充8个0x08 42 | padding_byte_size=8 43 | padding_data=('{:08b}'.format(padding_byte_size))*padding_byte_size 44 | last_group_data=padding_data 45 | bin_data_list.append(last_group_data) 46 | return bin_data_list 47 | else: 48 | padding_length = 64 - data_length 49 | padding_byte_size = (padding_length)//8 50 | #填充采用 PKCS#5填充标准 51 | padding_data = ('{:08b}'.format(padding_byte_size))*padding_byte_size 52 | last_group_data = bin_data + padding_data 53 | bin_data_list.append(last_group_data) #填加最后填充的内容 54 | print("最后需填充的字节数为 ",padding_byte_size) 55 | print("最后一个分组的长度为 ",len(last_group_data)) 56 | return bin_data_list 57 | #将明文分组信息储存在txt文件中,便于2组内加密中获取相应的明文数据 58 | def save_group_data(bin_data_list): 59 | f=open('group_data.txt','w') 60 | for i in bin_data_list: 61 | f.write(i+'\n') 62 | f.close() 63 | 64 | def main(): 65 | #需要转换为01比特序列的图片名 66 | img_dir="original_img.png" 67 | #获取图像的像素点 68 | print("*** 正在获取图像信息 ***") 69 | bin_data,img_width,img_height=get_pixel(img_dir) 70 | print('图像宽度:',img_width,'图像高度:',img_height) 71 | bin_data_list=set_group(bin_data) 72 | save_group_data(bin_data_list) 73 | print("*** 保存明文分组信息成功 ***") 74 | print("*** 明文分组信息存储在group.txt文件中 ***") 75 | # print("最终获取的明文分组为:",bin_data_list) 76 | 77 | if __name__ == '__main__': 78 | main() 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /2组内加密.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 2组内加密: 5 | 说明:本代码旨在将得到的分组后的数据进行DES加密的处理,这里可以选用 6 | 二重DES或三重DES加密算法,以提升加密的安全性 7 | ''' 8 | import random 9 | import os 10 | # 密钥置换选择 1 11 | key_table1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] 12 | # 密钥置换选择 2 13 | key_table2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] 14 | # 初始置换 IP 15 | IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] 16 | # 逆初始置换 17 | IP_1 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24] 18 | # 选择扩展运算 E 19 | E = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] 20 | # 置换运算 P 21 | P = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] 22 | # S盒 23 | sbox = [ 24 | # S1 25 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 26 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 27 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 28 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], 29 | # S2 30 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 31 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 32 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 33 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], 34 | # S3 35 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 36 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 37 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 38 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 39 | 40 | # S4 41 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 42 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 43 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 44 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], 45 | 46 | # S5 47 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 48 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 49 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 50 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], 51 | 52 | # S6 53 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 54 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 55 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 56 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], 57 | 58 | # S7 59 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 60 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 61 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 62 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], 63 | 64 | # S8 65 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 66 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 67 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 68 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], 69 | ] 70 | 71 | #循环左移位数 72 | l=[1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] 73 | 74 | #检测64位密钥的奇偶校验是否通过 75 | def check_key(key_bin): 76 | for i in range(0,64,8): 77 | xor=int(key_bin[i])^int(key_bin[i+1])^int(key_bin[i+2])^int(key_bin[i+3])^int(key_bin[i+4])^int(key_bin[i+5])^int(key_bin[i+6]) 78 | if xor!=int(key_bin[i+7]): 79 | return False 80 | return True 81 | 82 | #密钥置换选择1 83 | def key_ds1(key): 84 | s='' 85 | for i in key_table1: 86 | s+=key[i] 87 | return s 88 | #密钥置换选择2 89 | def key_ds2(key): 90 | s='' 91 | for i in key_table2: 92 | s+=key[i] 93 | return s 94 | #密钥循环左移 95 | def key_move(key,r): 96 | s=key 97 | for i in range(l[r]): 98 | s=s[1:]+s[:1] 99 | return s 100 | #扩展置换E 101 | def extend_E(R): 102 | r='' 103 | for i in E: 104 | r+=R[i] 105 | return r 106 | #代换选择S盒 107 | def alter_s(t): 108 | j=0 109 | res='' 110 | for i in range(0,48,6): 111 | c=int(t[i+1:i+5],2) 112 | r=int(t[i]+t[i+5],2) 113 | res+='{:04b}'.format((sbox[j][r*16+c])) 114 | j+=1 115 | # print(res) 116 | return res 117 | #P置换 118 | def p_repl(s): 119 | p='' 120 | for i in P: 121 | p+=s[i] 122 | return p 123 | 124 | #通过64位密钥获取全部的子密钥 125 | def get_subkey(key_bin): 126 | #首先进行key_bin的奇偶校验检查 127 | if check_key(key_bin)==False: 128 | print('密钥奇偶校验不通过!') 129 | return 130 | #print('密钥奇偶校验通过!') 131 | key=[] 132 | #密钥置换选择1 133 | key1_res=key_ds1(key_bin) 134 | L=key1_res[:28] 135 | R=key1_res[28:] 136 | for i in range(16): 137 | #循环左移 138 | L=key_move(L,i) 139 | R=key_move(R,i) 140 | #密钥置换选择2 141 | key.append(key_ds2(L+R)) 142 | return key 143 | 144 | 145 | #DES加密基本函数,输入64位明文和密钥 146 | def DES(M,key): 147 | #首先将明文进行初始置换IP 148 | m='' 149 | for i in IP: 150 | m+=M[i] 151 | L=[] 152 | R=[] 153 | # print('m=',m) 154 | L.append(m[:32]) 155 | R.append(m[32:]) 156 | #16轮feistel结构 157 | for i in range(16): 158 | L.append(R[i]) 159 | #将R进行扩展置换E 160 | R_extend=extend_E(R[i]) 161 | #优化算法 162 | # t='' 163 | # for j in range(48): 164 | # #print(R_extend[j],key[i][j]) 165 | # t+=str(int(R_extend[j])^int(key[i][j])) 166 | t='{:048b}'.format(int(R_extend,2)^int(key[i],2)) 167 | #代换选择S盒 168 | s=alter_s(t) 169 | #P置换 170 | p=p_repl(s) 171 | #优化算法 172 | # r='' 173 | # for j in range(32): 174 | # r+=str(int(p[j])^int(L[i][j])) 175 | r='{:032b}'.format(int(p,2)^int(L[i],2)) 176 | R.append(r) 177 | # print('l+r',L[i] + R[i]) 178 | #左右交换 179 | c=R[16]+L[16] 180 | #逆初始置换 181 | cipher='' 182 | for i in IP_1: 183 | cipher+=c[i] 184 | return cipher 185 | 186 | #随机生成满足奇偶校验的64位密钥 187 | def get_rand_key(p): 188 | key_seed=os.urandom(8) #随机获取8个字符 189 | KEY_bin_str='' 190 | for i in key_seed: 191 | binstr='{:07b}'.format(i) #将每个字符转成7位二进制,第8位用于表示奇偶校验位 192 | xor=int(binstr[0])^int(binstr[1])^int(binstr[2])^int(binstr[3])^int(binstr[4])^int(binstr[5])^int(binstr[6]) 193 | for i in range(7): 194 | KEY_bin_str+=str(binstr[i]) 195 | KEY_bin_str+=str(xor) 196 | # print(binstr[0],binstr[1],binstr[2],binstr[3],binstr[4],binstr[5],binstr[6],sep=' ^ ',end=' = ') 197 | # print(xor) 198 | #print('随机生成的密钥',p,'为: ',KEY_bin_str,' ',len(KEY_bin_str),'位') 199 | #print(len(KEY_bin_str)) 200 | return KEY_bin_str 201 | 202 | #DES加密函数 203 | def DES_encrypt(message_bin_data,sub_key,i): 204 | #print(sub_key[0]) 205 | print('正在利用密钥',i,'对数据进行DES加密') 206 | ciphertext=DES(message_bin_data,sub_key) 207 | print('加密后得到的二进制流为:',ciphertext,' ',len(ciphertext),'位') 208 | return ciphertext 209 | 210 | #DES解密函数 211 | def DES_decrypt(ciphertext,key,i): 212 | print('正在利用密钥',i,'对数据进行DES解密') 213 | plainbin=DES(ciphertext,key) 214 | print('解密后得到的二进制流为:',plainbin,' ',len(plainbin),'位') 215 | return plainbin 216 | 217 | #进行二重DES加密 218 | def DES_2_encrypt(s,sub_key1,sub_key2): 219 | # print("*** 开始进行二重DES加密 ***") 220 | #print("*** 正在随机生成DES密钥 ***") 221 | print("*** 正在进行二重DES加密 ***") 222 | ciphertext=DES_encrypt(s,sub_key1,1) 223 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 224 | return ciphertext 225 | def DES_2_decrypt(ciphertext,sub_key1,sub_key2): 226 | print("*** 正在进行二重DES解密 ***") 227 | sub_key1=sub_key1[::-1] 228 | sub_key2=sub_key2[::-1] 229 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 230 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 231 | return plaintext 232 | 233 | #三重DES加密 234 | def DES_3_encrypt(s,sub_key1,sub_key2,sub_key3): 235 | sub_key2=sub_key2[::-1] #解密密钥 236 | print("*** 正在进行三重DES加密 ***") 237 | ciphertext=DES_encrypt(s,sub_key1,1) 238 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 239 | ciphertext=DES_encrypt(ciphertext,sub_key3,3) 240 | print("*** 三重DES加密成功 ***") 241 | return ciphertext 242 | #三重DES解密 243 | def DES_3_decrypt(ciphertext,sub_key1,sub_key2,sub_key3): 244 | print("*** 正在进行三重DES解密 ***") 245 | sub_key1=sub_key1[::-1] 246 | sub_key2=sub_key2 #加密密钥 247 | sub_key3=sub_key3[::-1] 248 | ciphertext=DES_decrypt(ciphertext,sub_key3,3) 249 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 250 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 251 | print("*** 三重DES解密成功 ***") 252 | return plaintext 253 | 254 | #获取明文的全部分组 255 | def get_group(filename): 256 | group_list=[] 257 | f=open(filename,'r') 258 | for line in f: 259 | group_list.append(line.strip('\n')) 260 | f.close() 261 | return group_list 262 | 263 | def main(): 264 | #明文分组文件名 265 | group_file_name='group_data.txt' 266 | #获取分组列表 267 | group_list = get_group(group_file_name) 268 | #对所有明文分组进行加密 269 | for s in group_list: 270 | #s='0010001000011001111010110010000000100011111011100001110000100101' 271 | print('------------------------------------------------') 272 | print('初始选取的明文为: ',s) 273 | print("*** 正在随机生成DES密钥 ***") 274 | key_bin1=get_rand_key(1) 275 | key_bin2=get_rand_key(2) 276 | key_bin3=get_rand_key(3) 277 | sub_key1=get_subkey(key_bin1) 278 | sub_key2=get_subkey(key_bin2) 279 | sub_key3=get_subkey(key_bin3) 280 | #默认选用三重DES加密,也可以选择二重DES进行加密 281 | # ciphertext=DES_2_encrypt(s,sub_key1,sub_key2) 282 | # plaintext=DES_2_decrypt(ciphertext,sub_key1,sub_key2) 283 | ciphertext=DES_3_encrypt(s,sub_key1,sub_key2,sub_key3) 284 | plaintext=DES_3_decrypt(ciphertext,sub_key1,sub_key2,sub_key3) 285 | print("*** 对比原始数据和解密结果 ***") 286 | print("原始数据: ",s) 287 | print('解密结果: ',plaintext) 288 | print('------------------------------------------------') 289 | 290 | if __name__ == '__main__': 291 | main() 292 | 293 | 294 | -------------------------------------------------------------------------------- /3分组运行模式.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 3分组运行模式: 5 | 说明:本代码旨在利用密码分组链接(CBC)模式对明文分组进行加密, 6 | 选用三重DES加密模式进行加密 7 | ''' 8 | import random 9 | import os 10 | ############################################################ 11 | # *引用* # 12 | # 引用 2组内加密 相关代码进行三重DES加密 # # 13 | # 对其中的结果打印部分作注释 # 14 | ############################################################ 15 | # 密钥置换选择 1 16 | key_table1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] 17 | # 密钥置换选择 2 18 | key_table2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] 19 | # 初始置换 IP 20 | IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] 21 | # 逆初始置换 22 | IP_1 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24] 23 | # 选择扩展运算 E 24 | E = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] 25 | # 置换运算 P 26 | P = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] 27 | # S盒 28 | sbox = [ 29 | # S1 30 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 31 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 32 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 33 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], 34 | # S2 35 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 36 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 37 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 38 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], 39 | # S3 40 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 41 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 42 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 43 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 44 | 45 | # S4 46 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 47 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 48 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 49 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], 50 | 51 | # S5 52 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 53 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 54 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 55 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], 56 | 57 | # S6 58 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 59 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 60 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 61 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], 62 | 63 | # S7 64 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 65 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 66 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 67 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], 68 | 69 | # S8 70 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 71 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 72 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 73 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], 74 | ] 75 | 76 | #循环左移位数 77 | l=[1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] 78 | 79 | #检测64位密钥的奇偶校验是否通过 80 | def check_key(key_bin): 81 | for i in range(0,64,8): 82 | xor=int(key_bin[i])^int(key_bin[i+1])^int(key_bin[i+2])^int(key_bin[i+3])^int(key_bin[i+4])^int(key_bin[i+5])^int(key_bin[i+6]) 83 | if xor!=int(key_bin[i+7]): 84 | return False 85 | return True 86 | 87 | #密钥置换选择1 88 | def key_ds1(key): 89 | s='' 90 | for i in key_table1: 91 | s+=key[i] 92 | return s 93 | #密钥置换选择2 94 | def key_ds2(key): 95 | s='' 96 | for i in key_table2: 97 | s+=key[i] 98 | return s 99 | #密钥循环左移 100 | def key_move(key,r): 101 | # print('key=',key,'len=',len(key)) 102 | # s = key[l[r] : ] + key[ : l[r]][::-1] 103 | s=key 104 | for i in range(l[r]): 105 | s=s[1:]+s[:1] 106 | # print('s=',s,'len=',len(s)) 107 | return s 108 | #通过64位密钥获取全部的子密钥 109 | def get_subkey(key_bin): 110 | #首先进行key_bin的奇偶校验检查 111 | if check_key(key_bin)==False: 112 | print('密钥奇偶校验不通过!') 113 | return 114 | #print('密钥奇偶校验通过!') 115 | key=[] 116 | #密钥置换选择1 117 | key1_res=key_ds1(key_bin) 118 | # print(key1_res,len(key1_res)) 119 | L=key1_res[:28] 120 | R=key1_res[28:] 121 | # print('l=',L,len(L)) 122 | # print('r=',R,len(R)) 123 | for i in range(16): 124 | #循环左移 125 | L=key_move(L,i) 126 | R=key_move(R,i) 127 | #密钥置换选择2 128 | key.append(key_ds2(L+R)) 129 | # print('keys:') 130 | # for i in key: 131 | # print(i) 132 | #print('16轮子密钥成功生成!') 133 | # print('key=',key) 134 | return key 135 | 136 | #扩展置换E 137 | def extend_E(R): 138 | r='' 139 | for i in E: 140 | r+=R[i] 141 | return r 142 | #代换选择S盒 143 | def alter_s(t): 144 | j=0 145 | res='' 146 | for i in range(0,48,6): 147 | c=int(t[i+1:i+5],2) 148 | r=int(t[i]+t[i+5],2) 149 | res+='{:04b}'.format((sbox[j][r*16+c])) 150 | j+=1 151 | # print(res) 152 | return res 153 | #P置换 154 | def p_repl(s): 155 | p='' 156 | for i in P: 157 | p+=s[i] 158 | return p 159 | 160 | #DES加密基本函数,输入64位明文和密钥 161 | def DES(M,key): 162 | #首先将明文进行初始置换IP 163 | m='' 164 | for i in IP: 165 | m+=M[i] 166 | L=[] 167 | R=[] 168 | # print('m=',m) 169 | L.append(m[:32]) 170 | R.append(m[32:]) 171 | #16轮feistel结构 172 | for i in range(16): 173 | L.append(R[i]) 174 | #将R进行扩展置换E 175 | R_extend=extend_E(R[i]) 176 | #异或子密钥 K(i) 177 | #print('r=',R_extend) 178 | 179 | #优化算法 180 | # t='' 181 | # for j in range(48): 182 | # #print(R_extend[j],key[i][j]) 183 | # t+=str(int(R_extend[j])^int(key[i][j])) 184 | t='{:048b}'.format(int(R_extend,2)^int(key[i],2)) 185 | # print('t=',t) 186 | #代换选择S盒 187 | s=alter_s(t) 188 | # print('s=',s) 189 | #P置换 190 | p=p_repl(s) 191 | #异或L(i-1) 192 | # print('p=', p) 193 | 194 | #优化算法 195 | # r='' 196 | # for j in range(32): 197 | # r+=str(int(p[j])^int(L[i][j])) 198 | r='{:032b}'.format(int(p,2)^int(L[i],2)) 199 | R.append(r) 200 | # print('l+r',L[i] + R[i]) 201 | #左右交换 202 | c=R[16]+L[16] 203 | #逆初始置换 204 | cipher='' 205 | for i in IP_1: 206 | cipher+=c[i] 207 | return cipher 208 | 209 | #随机生成满足奇偶校验的64位密钥 210 | def get_rand_key(p): 211 | key_seed=os.urandom(8) #随机获取8个字符 212 | KEY_bin_str='' 213 | for i in key_seed: 214 | binstr='{:07b}'.format(i) #将每个字符转成7位二进制,第8位用于表示奇偶校验位 215 | xor=int(binstr[0])^int(binstr[1])^int(binstr[2])^int(binstr[3])^int(binstr[4])^int(binstr[5])^int(binstr[6]) 216 | for i in range(7): 217 | KEY_bin_str+=str(binstr[i]) 218 | KEY_bin_str+=str(xor) 219 | # print(binstr[0],binstr[1],binstr[2],binstr[3],binstr[4],binstr[5],binstr[6],sep=' ^ ',end=' = ') 220 | # print(xor) 221 | #print('随机生成的密钥',p,'为: ',KEY_bin_str,' ',len(KEY_bin_str),'位') 222 | # print(len(KEY_bin_str)) 223 | return KEY_bin_str 224 | 225 | #DES加密函数 226 | def DES_encrypt(message_bin_data,sub_key,i): 227 | #print(sub_key[0]) 228 | # print('正在利用密钥',i,'对数据进行DES加密') 229 | ciphertext=DES(message_bin_data,sub_key) 230 | # print('加密后得到的二进制流为:',ciphertext,' ',len(ciphertext),'位') 231 | return ciphertext 232 | 233 | #DES解密函数 234 | def DES_decrypt(ciphertext,key,i): 235 | # print('正在利用密钥',i,'对数据进行DES解密') 236 | plainbin=DES(ciphertext,key) 237 | # print('解密后得到的二进制流为:',plainbin,' ',len(plainbin),'位') 238 | return plainbin 239 | 240 | #进行二重DES加密 241 | def DES_2_encrypt(s,sub_key1,sub_key2): 242 | # print("*** 开始进行二重DES加密 ***") 243 | #print("*** 正在随机生成DES密钥 ***") 244 | # print("*** 正在进行二重DES加密 ***") 245 | ciphertext=DES_encrypt(s,sub_key1,1) 246 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 247 | return ciphertext 248 | def DES_2_decrypt(ciphertext,sub_key1,sub_key2): 249 | # print("*** 正在进行二重DES解密 ***") 250 | sub_key1=sub_key1[::-1] 251 | sub_key2=sub_key2[::-1] 252 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 253 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 254 | return plaintext 255 | 256 | #三重DES加密 257 | def DES_3_encrypt(s,sub_key1,sub_key2,sub_key3): 258 | #print(sub_key1[0]) 259 | sub_key2=sub_key2[::-1] #解密密钥 260 | # print("*** 正在进行三重DES加密 ***") 261 | ciphertext=DES_encrypt(s,sub_key1,1) 262 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 263 | ciphertext=DES_encrypt(ciphertext,sub_key3,3) 264 | return ciphertext 265 | #三重DES解密 266 | def DES_3_decrypt(ciphertext,sub_key1,sub_key2,sub_key3): 267 | # print("*** 正在进行三重DES解密 ***") 268 | sub_key1=sub_key1[::-1] 269 | sub_key2=sub_key2 #加密密钥 270 | sub_key3=sub_key3[::-1] 271 | ciphertext=DES_decrypt(ciphertext,sub_key3,3) 272 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 273 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 274 | # print("*** 三重DES解密成功 ***") 275 | return plaintext 276 | 277 | ############################################################ 278 | # # 279 | # *结束引用* # 280 | # # 281 | ############################################################ 282 | #获取明文的全部分组 283 | def get_group(filename): 284 | group_list=[] 285 | f=open(filename,'r') 286 | for line in f: 287 | group_list.append(line.strip('\n')) 288 | f.close() 289 | return group_list 290 | #获取初始IV向量 291 | def get_IV(): 292 | iv_seed=os.urandom(8) #随机获取8个字符 293 | iv_bin_str='' 294 | for i in iv_seed: 295 | iv_bin_str+='{:08b}'.format(i) 296 | return iv_bin_str 297 | #CBC加密 298 | def CBC_encrypt(group_list,iv,key_bin1,key_bin2,key_bin3): 299 | print("*** 正在获取子密钥 ***") 300 | sub_key1=get_subkey(key_bin1) 301 | sub_key2=get_subkey(key_bin2) 302 | sub_key3=get_subkey(key_bin3) 303 | C_list=[] 304 | Iv=iv 305 | print("*** 正在进行CBC加密 ***") 306 | for group in group_list: 307 | xor_res='' 308 | # for i in range(64): 309 | # xor_res+=str(int(group[i])^int(Iv[i])) 310 | #优化算法 311 | xor_res='{:064b}'.format(int(group,2)^int(Iv,2)) 312 | C=DES_3_encrypt(xor_res,sub_key1,sub_key2,sub_key3) 313 | C_list.append(C) 314 | Iv=C 315 | return C_list 316 | #CBC解密 317 | def CBC_decrypt(C_list,iv,key_bin1,key_bin2,key_bin3): 318 | sub_key1=get_subkey(key_bin1) 319 | sub_key2=get_subkey(key_bin2) 320 | sub_key3=get_subkey(key_bin3) 321 | P_list=[] 322 | Iv=iv 323 | for c in C_list: 324 | res=DES_3_decrypt(c,sub_key1,sub_key2,sub_key3) 325 | xor_res='' 326 | # for i in range(64): 327 | # xor_res+=str(int(res[i])^int(Iv[i])) 328 | #优化算法,加快运算速度 329 | xor_res='{:064b}'.format(int(res,2)^int(Iv,2)) 330 | P_list.append(xor_res) 331 | Iv=c 332 | return P_list 333 | #存储加密后的分组信息 334 | def save_img_data(filename,list_data): 335 | f=open(filename,'w') 336 | for i in list_data: 337 | f.write(i+'\n') 338 | f.close() 339 | 340 | def save_iv_data(filename,iv): 341 | f=open(filename,'w') 342 | f.write(iv+'\n') 343 | f.close() 344 | 345 | def save_keys(filename,key_bin1,key_bin2,key_bin3): 346 | f=open(filename,'w') 347 | f.write(key_bin1+'\n') 348 | f.write(key_bin2+'\n') 349 | f.write(key_bin3+'\n') 350 | f.close() 351 | 352 | 353 | def main(): 354 | #明文分组文件名 355 | group_file_name='group_data.txt' 356 | #获取分组列表 357 | group_list = get_group(group_file_name) 358 | #获取初始向量IV 359 | iv=get_IV() 360 | #随机生成3个DES密钥 361 | key_bin1=get_rand_key(1) 362 | key_bin2=get_rand_key(2) 363 | key_bin3=get_rand_key(3) 364 | #进行CBC模型下的三重DES加密 365 | c_list=CBC_encrypt(group_list,iv,key_bin1,key_bin2,key_bin3) 366 | #CBC模型下的三重DES解密 367 | #p_list=CBC_decrypt(c_list,iv,key_bin1,key_bin2,key_bin3) 368 | #保存加密后分组数据便于 4密文图像显示 369 | save_img_data('encrypt_data.txt',c_list) 370 | #保存初始向量IV信息用于解密 371 | save_iv_data('iv.txt',iv) 372 | #保存解密数据 373 | #save_data('decrypt_data.txt',p_list) 374 | #保存密钥信息 375 | save_keys('keys.txt',key_bin1,key_bin2,key_bin3) 376 | print("*** 相关信息保存成功! ***") 377 | 378 | if __name__ == '__main__': 379 | main() 380 | 381 | 382 | -------------------------------------------------------------------------------- /4密文图像显示.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 4密文图像显示: 5 | 说明:本代码旨在将加密后像素值重新绘制成密文图像 6 | ''' 7 | from PIL import Image 8 | #获取图像的宽高 9 | def get_img_inf(img): 10 | im = Image.open(img) 11 | return im.size[0],im.size[1] 12 | #获取加密后的像素信息 13 | def get_img_data(filename): 14 | img_data='' 15 | f=open(filename,'r') 16 | for line in f: 17 | img_data+=(line.strip('\n')) 18 | f.close() 19 | return img_data 20 | #绘制加密后的图像 21 | def draw_image(img_data,img_filename,img_width,img_height): 22 | img = Image.new('RGB',(img_width,img_height)) 23 | c=0 24 | for i in range(img_width): 25 | for j in range(img_height): 26 | r=int(img_data[c:c+8],2) 27 | g=int(img_data[c+8:c+16],2) 28 | b=int(img_data[c+16:c+24],2) 29 | # print('绘制加密图片',i,j,r,g,b,sep=' ') 30 | img.putpixel((i,j),(r,g,b)) 31 | c+=24 32 | img.save(img_filename) 33 | 34 | 35 | def main(): 36 | ori_img='original_img.png' 37 | img_width,img_height=get_img_inf(ori_img) 38 | #通过加密后的分组信息绘制密文图像 39 | filename='encrypt_data.txt' 40 | img_data=get_img_data(filename) 41 | img_filename='encrypted_img.png' 42 | draw_image(img_data,img_filename,img_width,img_height) 43 | print('绘制加密图片成功!') 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /5密文图像解密.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 5密文图像解密: 5 | 说明:本代码旨在利用加密后的图像和密钥文件keys.txt解密 6 | 像数值数据并恢复密文图像 7 | ''' 8 | from PIL import Image 9 | 10 | ############################################################ 11 | # *引用* # 12 | # 引用 1数字图像处理 相关代码获取加密图像相关信息 # 13 | # # 14 | ############################################################ 15 | #图片像素二进制值获取函数 16 | def get_pixel(img): 17 | im = Image.open(img) 18 | rgb_im = im.convert('RGB') 19 | img_width=im.size[0] 20 | img_height=im.size[1] 21 | bin_data='' 22 | for i in range(img_width): 23 | for j in range(img_height): 24 | r, g, b = rgb_im.getpixel((i, j)) #获取像素点的rgb值 25 | # print(r, g, b) 26 | bin_data+='{:08b}'.format(r) 27 | bin_data+='{:08b}'.format(g) 28 | bin_data+='{:08b}'.format(b) 29 | return bin_data,img_width,img_height 30 | 31 | #DES明文分组处理函数 32 | def set_group(bin_data): 33 | print("*** 正在进行明文分组 ***") 34 | bin_data_list=[] 35 | data_length=len(bin_data) 36 | i=0 37 | while data_length>=64: #按照 38 | #print("正在划分第"+str(i)+"个明文分组 ",data_length) 39 | bin_data_list.append(bin_data[:64]) 40 | data_length-=64 41 | bin_data=bin_data[64:] 42 | i+=1 43 | print("正在处理最后一个明文分组 ",data_length) 44 | if data_length == 0: #若恰好能够完全分组 45 | return bin_data_list 46 | else: 47 | padding_length = 64 - data_length 48 | padding_byte_size = (padding_length)//8 49 | #填充采用 PKCS#5填充标准 50 | padding_data = ('{:08b}'.format(padding_byte_size))*padding_byte_size 51 | last_group_data = bin_data + padding_data 52 | bin_data_list.append(last_group_data) #填加最后填充的内容 53 | print("最后需填充的字节数为 ",padding_byte_size) 54 | print("最后一个分组的长度为 ",len(last_group_data)) 55 | return bin_data_list 56 | ############################################################ 57 | # # 58 | # *结束引用* # 59 | # # 60 | ############################################################ 61 | ############################################################ 62 | # *引用* # 63 | # 引用 3分组运行模型 相关代码进行CBC解密 # 64 | # 对其中的结果打印部分作注释 # 65 | ############################################################ 66 | # 密钥置换选择 1 67 | key_table1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] 68 | # 密钥置换选择 2 69 | key_table2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] 70 | # 初始置换 IP 71 | IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] 72 | # 逆初始置换 73 | IP_1 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24] 74 | # 选择扩展运算 E 75 | E = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] 76 | # 置换运算 P 77 | P = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] 78 | # S盒 79 | sbox = [ 80 | # S1 81 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 82 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 83 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 84 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], 85 | # S2 86 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 87 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 88 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 89 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], 90 | # S3 91 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 92 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 93 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 94 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 95 | 96 | # S4 97 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 98 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 99 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 100 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], 101 | 102 | # S5 103 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 104 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 105 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 106 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], 107 | 108 | # S6 109 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 110 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 111 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 112 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], 113 | 114 | # S7 115 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 116 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 117 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 118 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], 119 | 120 | # S8 121 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 122 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 123 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 124 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], 125 | ] 126 | 127 | #循环左移位数 128 | l=[1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] 129 | 130 | #检测64位密钥的奇偶校验是否通过 131 | def check_key(key_bin): 132 | for i in range(0,64,8): 133 | xor=int(key_bin[i])^int(key_bin[i+1])^int(key_bin[i+2])^int(key_bin[i+3])^int(key_bin[i+4])^int(key_bin[i+5])^int(key_bin[i+6]) 134 | if xor!=int(key_bin[i+7]): 135 | return False 136 | return True 137 | 138 | #密钥置换选择1 139 | def key_ds1(key): 140 | s='' 141 | for i in key_table1: 142 | s+=key[i] 143 | return s 144 | #密钥置换选择2 145 | def key_ds2(key): 146 | s='' 147 | for i in key_table2: 148 | s+=key[i] 149 | return s 150 | #密钥循环左移 151 | def key_move(key,r): 152 | # print('key=',key,'len=',len(key)) 153 | # s = key[l[r] : ] + key[ : l[r]][::-1] 154 | s=key 155 | for i in range(l[r]): 156 | s=s[1:]+s[:1] 157 | # print('s=',s,'len=',len(s)) 158 | return s 159 | #通过64位密钥获取全部的子密钥 160 | def get_subkey(key_bin): 161 | #首先进行key_bin的奇偶校验检查 162 | if check_key(key_bin)==False: 163 | print('密钥奇偶校验不通过!') 164 | return 165 | #print('密钥奇偶校验通过!') 166 | key=[] 167 | #密钥置换选择1 168 | key1_res=key_ds1(key_bin) 169 | # print(key1_res,len(key1_res)) 170 | L=key1_res[:28] 171 | R=key1_res[28:] 172 | # print('l=',L,len(L)) 173 | # print('r=',R,len(R)) 174 | for i in range(16): 175 | #循环左移 176 | L=key_move(L,i) 177 | R=key_move(R,i) 178 | #密钥置换选择2 179 | key.append(key_ds2(L+R)) 180 | # print('keys:') 181 | # for i in key: 182 | # print(i) 183 | #print('16轮子密钥成功生成!') 184 | # print('key=',key) 185 | return key 186 | 187 | #扩展置换E 188 | def extend_E(R): 189 | r='' 190 | for i in E: 191 | r+=R[i] 192 | return r 193 | #代换选择S盒 194 | def alter_s(t): 195 | j=0 196 | res='' 197 | for i in range(0,48,6): 198 | c=int(t[i+1:i+5],2) 199 | r=int(t[i]+t[i+5],2) 200 | res+='{:04b}'.format((sbox[j][r*16+c])) 201 | j+=1 202 | # print(res) 203 | return res 204 | #P置换 205 | def p_repl(s): 206 | p='' 207 | for i in P: 208 | p+=s[i] 209 | return p 210 | 211 | #DES加密基本函数,输入64位明文和密钥 212 | def DES(M,key): 213 | #首先将明文进行初始置换IP 214 | m='' 215 | for i in IP: 216 | m+=M[i] 217 | L=[] 218 | R=[] 219 | # print('m=',m) 220 | L.append(m[:32]) 221 | R.append(m[32:]) 222 | #16轮feistel结构 223 | for i in range(16): 224 | L.append(R[i]) 225 | #将R进行扩展置换E 226 | R_extend=extend_E(R[i]) 227 | #异或子密钥 K(i) 228 | #print('r=',R_extend) 229 | 230 | #优化算法 231 | # t='' 232 | # for j in range(48): 233 | # #print(R_extend[j],key[i][j]) 234 | # t+=str(int(R_extend[j])^int(key[i][j])) 235 | t='{:048b}'.format(int(R_extend,2)^int(key[i],2)) 236 | # print('t=',t) 237 | #代换选择S盒 238 | s=alter_s(t) 239 | # print('s=',s) 240 | #P置换 241 | p=p_repl(s) 242 | #异或L(i-1) 243 | # print('p=', p) 244 | 245 | #优化算法 246 | # r='' 247 | # for j in range(32): 248 | # r+=str(int(p[j])^int(L[i][j])) 249 | r='{:032b}'.format(int(p,2)^int(L[i],2)) 250 | R.append(r) 251 | # print('l+r',L[i] + R[i]) 252 | #左右交换 253 | c=R[16]+L[16] 254 | #逆初始置换 255 | cipher='' 256 | for i in IP_1: 257 | cipher+=c[i] 258 | return cipher 259 | 260 | #随机生成满足奇偶校验的64位密钥 261 | def get_rand_key(p): 262 | key_seed=os.urandom(8) #随机获取8个字符 263 | KEY_bin_str='' 264 | for i in key_seed: 265 | binstr='{:07b}'.format(i) #将每个字符转成7位二进制,第8位用于表示奇偶校验位 266 | xor=int(binstr[0])^int(binstr[1])^int(binstr[2])^int(binstr[3])^int(binstr[4])^int(binstr[5])^int(binstr[6]) 267 | for i in range(7): 268 | KEY_bin_str+=str(binstr[i]) 269 | KEY_bin_str+=str(xor) 270 | # print(binstr[0],binstr[1],binstr[2],binstr[3],binstr[4],binstr[5],binstr[6],sep=' ^ ',end=' = ') 271 | # print(xor) 272 | #print('随机生成的密钥',p,'为: ',KEY_bin_str,' ',len(KEY_bin_str),'位') 273 | # print(len(KEY_bin_str)) 274 | return KEY_bin_str 275 | 276 | #DES加密函数 277 | def DES_encrypt(message_bin_data,sub_key,i): 278 | #print(sub_key[0]) 279 | # print('正在利用密钥',i,'对数据进行DES加密') 280 | ciphertext=DES(message_bin_data,sub_key) 281 | # print('加密后得到的二进制流为:',ciphertext,' ',len(ciphertext),'位') 282 | return ciphertext 283 | 284 | #DES解密函数 285 | def DES_decrypt(ciphertext,key,i): 286 | # print('正在利用密钥',i,'对数据进行DES解密') 287 | plainbin=DES(ciphertext,key) 288 | # print('解密后得到的二进制流为:',plainbin,' ',len(plainbin),'位') 289 | return plainbin 290 | 291 | #进行二重DES加密 292 | def DES_2_encrypt(s,sub_key1,sub_key2): 293 | # print("*** 开始进行二重DES加密 ***") 294 | #print("*** 正在随机生成DES密钥 ***") 295 | # print("*** 正在进行二重DES加密 ***") 296 | ciphertext=DES_encrypt(s,sub_key1,1) 297 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 298 | return ciphertext 299 | def DES_2_decrypt(ciphertext,sub_key1,sub_key2): 300 | # print("*** 正在进行二重DES解密 ***") 301 | sub_key1=sub_key1[::-1] 302 | sub_key2=sub_key2[::-1] 303 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 304 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 305 | return plaintext 306 | 307 | #三重DES加密 308 | def DES_3_encrypt(s,sub_key1,sub_key2,sub_key3): 309 | #print(sub_key1[0]) 310 | sub_key2=sub_key2[::-1] #解密密钥 311 | # print("*** 正在进行三重DES加密 ***") 312 | ciphertext=DES_encrypt(s,sub_key1,1) 313 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 314 | ciphertext=DES_encrypt(ciphertext,sub_key3,3) 315 | return ciphertext 316 | #三重DES解密 317 | def DES_3_decrypt(ciphertext,sub_key1,sub_key2,sub_key3): 318 | # print("*** 正在进行三重DES解密 ***") 319 | sub_key1=sub_key1[::-1] 320 | sub_key2=sub_key2 #加密密钥 321 | sub_key3=sub_key3[::-1] 322 | ciphertext=DES_decrypt(ciphertext,sub_key3,3) 323 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 324 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 325 | # print("*** 三重DES解密成功 ***") 326 | return plaintext 327 | 328 | #获取明文的全部分组 329 | def get_group(filename): 330 | group_list=[] 331 | f=open(filename,'r') 332 | for line in f: 333 | group_list.append(line.strip('\n')) 334 | f.close() 335 | return group_list 336 | #获取初始IV向量 337 | def get_IV(): 338 | iv_seed=os.urandom(8) #随机获取8个字符 339 | iv_bin_str='' 340 | for i in iv_seed: 341 | iv_bin_str+='{:08b}'.format(i) 342 | return iv_bin_str 343 | #CBC加密 344 | def CBC_encrypt(group_list,iv,key_bin1,key_bin2,key_bin3): 345 | print("*** 正在获取子密钥 ***") 346 | sub_key1=get_subkey(key_bin1) 347 | sub_key2=get_subkey(key_bin2) 348 | sub_key3=get_subkey(key_bin3) 349 | C_list=[] 350 | Iv=iv 351 | print("*** 正在进行CBC加密 ***") 352 | for group in group_list: 353 | xor_res='' 354 | # for i in range(64): 355 | # xor_res+=str(int(group[i])^int(Iv[i])) 356 | #优化算法 357 | xor_res='{:064b}'.format(int(group,2)^int(Iv,2)) 358 | C=DES_3_encrypt(xor_res,sub_key1,sub_key2,sub_key3) 359 | C_list.append(C) 360 | Iv=C 361 | return C_list 362 | #CBC解密 363 | def CBC_decrypt(C_list,iv,key_bin1,key_bin2,key_bin3): 364 | sub_key1=get_subkey(key_bin1) 365 | sub_key2=get_subkey(key_bin2) 366 | sub_key3=get_subkey(key_bin3) 367 | P_list=[] 368 | Iv=iv 369 | for c in C_list: 370 | res=DES_3_decrypt(c,sub_key1,sub_key2,sub_key3) 371 | xor_res='' 372 | # for i in range(64): 373 | # xor_res+=str(int(res[i])^int(Iv[i])) 374 | #优化算法,加快运算速度 375 | xor_res='{:064b}'.format(int(res,2)^int(Iv,2)) 376 | P_list.append(xor_res) 377 | Iv=c 378 | return P_list 379 | ############################################################ 380 | # # 381 | # *结束引用* # 382 | # # 383 | ############################################################ 384 | 385 | 386 | #获取密钥信息函数 387 | def get_keys(filename): 388 | f=open(filename,'r') 389 | keys=[] 390 | for line in f: 391 | keys.append(line.strip('\n')) 392 | return keys[0],keys[1],keys[2] 393 | #获取iv信息 394 | def get_iv(filename): 395 | f=open(filename,'r') 396 | return f.readline().strip('\n') 397 | #获取加密图像的像素信息 398 | def get_img_data(filename): 399 | img_data='' 400 | f=open(filename,'r') 401 | for line in f: 402 | img_data+=(line.strip('\n')) 403 | f.close() 404 | return img_data 405 | #绘制解密图像信息 406 | def draw_image(img_data,img_filename,img_width,img_height): 407 | img = Image.new('RGB',(img_width,img_height)) 408 | c=0 409 | for i in range(img_width): 410 | for j in range(img_height): 411 | r=int(img_data[c:c+8],2) 412 | g=int(img_data[c+8:c+16],2) 413 | b=int(img_data[c+16:c+24],2) 414 | # print('绘制加密图片',i,j,r,g,b,sep=' ') 415 | img.putpixel((i,j),(r,g,b)) 416 | c+=24 417 | img.save(img_filename) 418 | 419 | 420 | 421 | 422 | def main(): 423 | print('*** 正在进行密文图像解密 ***') 424 | #加密图像 425 | enc_img='encrypted_img.png' 426 | #密钥文件 427 | keys_file='keys.txt' 428 | #iv文件 429 | iv_file='iv.txt' 430 | #获取加密后图像的像素值和宽高 431 | bin_data,img_width,img_height=get_pixel(enc_img) 432 | print('*** 获取加密图像数据成功! ***') 433 | #获取密钥信息 434 | key_bin1,key_bin2,key_bin3=get_keys(keys_file) 435 | print('*** 获取密钥信息成功! ****') 436 | #获取初始向量IV 437 | iv=get_iv(iv_file) 438 | #对加密数据进行分组 439 | bin_data_list=set_group(bin_data) 440 | #获取解密的分组信息 441 | p_list=CBC_decrypt(bin_data_list,iv,key_bin1,key_bin2,key_bin3) 442 | img_data=''.join(p_list) 443 | img_filename='decrypted_img.png' 444 | #绘制解密图像 445 | draw_image(img_data,img_filename,img_width,img_height) 446 | print('绘制解密图片成功!') 447 | 448 | if __name__ == '__main__': 449 | main() 450 | 451 | 452 | 453 | -------------------------------------------------------------------------------- /6三重DES和CBC分组加密实现.py: -------------------------------------------------------------------------------- 1 | #encoding=utf-8 2 | ''' 3 | Author: MonsterFanSec 4 | 1数字图像处理 5 | 说明:本代码旨在提取图片中的像素点,将每个像素点的RGB值转换为 6 | 二进制的01比特序列,再将得到的比特序列按照DES明文分组要求进行 7 | 64比特的明文分组,采用了PKCS#5填充标准进行填充,最终得到分组 8 | 的list列表 9 | ''' 10 | from PIL import Image 11 | 12 | #图片像素二进制值获取函数 13 | def get_pixel(img): 14 | im = Image.open(img) 15 | rgb_im = im.convert('RGB') 16 | img_width=im.size[0] #获取图像的宽 17 | img_height=im.size[1] #获取图像的高 18 | bin_data='' 19 | for i in range(img_width): #遍历每一个像素点 20 | for j in range(img_height): 21 | r, g, b = rgb_im.getpixel((i, j)) #获取像素点的rgb值 22 | # print(r, g, b) 23 | bin_data+='{:08b}'.format(r) 24 | bin_data+='{:08b}'.format(g) 25 | bin_data+='{:08b}'.format(b) 26 | return bin_data,img_width,img_height 27 | 28 | #DES明文分组处理函数 29 | def set_group(bin_data): 30 | print("*** 正在进行明文分组 ***") 31 | bin_data_list=[] 32 | data_length=len(bin_data) 33 | i=0 34 | while data_length>=64: #按照 35 | #print("正在划分第"+str(i)+"个明文分组 ",data_length) 36 | bin_data_list.append(bin_data[:64]) 37 | data_length-=64 38 | bin_data=bin_data[64:] 39 | i+=1 40 | print("正在处理最后一个明文分组 ",data_length) 41 | if data_length == 0: #若恰好能够完全分组 填充一定要进行,填充8个0x08 42 | padding_byte_size=8 43 | padding_data=('{:08b}'.format(padding_byte_size))*padding_byte_size 44 | last_group_data=padding_data 45 | bin_data_list.append(last_group_data) 46 | return bin_data_list 47 | else: 48 | padding_length = 64 - data_length 49 | padding_byte_size = (padding_length)//8 50 | #填充采用 PKCS#5填充标准 51 | padding_data = ('{:08b}'.format(padding_byte_size))*padding_byte_size 52 | last_group_data = bin_data + padding_data 53 | bin_data_list.append(last_group_data) #填加最后填充的内容 54 | print("最后需填充的字节数为 ",padding_byte_size) 55 | print("最后一个分组的长度为 ",len(last_group_data)) 56 | return bin_data_list 57 | #将明文分组信息储存在txt文件中,便于2组内加密中获取相应的明文数据 58 | def save_group_data(bin_data_list): 59 | f=open('group_data.txt','w') 60 | for i in bin_data_list: 61 | f.write(i+'\n') 62 | f.close() 63 | 64 | ''' 65 | 3分组运行模式: 66 | 说明:本代码旨在利用密码分组链接(CBC)模式对明文分组进行加密, 67 | 选用三重DES加密模式进行加密 68 | ''' 69 | import random 70 | import os 71 | ############################################################ 72 | # *引用* # 73 | # 引用 2组内加密 相关代码进行三重DES加密 # # 74 | # 对其中的结果打印部分作注释 # 75 | ############################################################ 76 | # 密钥置换选择 1 77 | key_table1 = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] 78 | # 密钥置换选择 2 79 | key_table2 = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] 80 | # 初始置换 IP 81 | IP = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] 82 | # 逆初始置换 83 | IP_1 = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40, 8, 48, 16, 56, 24] 84 | # 选择扩展运算 E 85 | E = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] 86 | # 置换运算 P 87 | P = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] 88 | # S盒 89 | sbox = [ 90 | # S1 91 | [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 92 | 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 93 | 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 94 | 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13], 95 | # S2 96 | [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 97 | 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 98 | 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 99 | 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9], 100 | # S3 101 | [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 102 | 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 103 | 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 104 | 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12], 105 | 106 | # S4 107 | [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 108 | 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 109 | 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 110 | 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14], 111 | 112 | # S5 113 | [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 114 | 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 115 | 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 116 | 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3], 117 | 118 | # S6 119 | [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 120 | 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 121 | 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 122 | 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13], 123 | 124 | # S7 125 | [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 126 | 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 127 | 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 128 | 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], 129 | 130 | # S8 131 | [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 132 | 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 133 | 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 134 | 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11], 135 | ] 136 | 137 | #循环左移位数 138 | l=[1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1] 139 | 140 | #检测64位密钥的奇偶校验是否通过 141 | def check_key(key_bin): 142 | for i in range(0,64,8): 143 | xor=int(key_bin[i])^int(key_bin[i+1])^int(key_bin[i+2])^int(key_bin[i+3])^int(key_bin[i+4])^int(key_bin[i+5])^int(key_bin[i+6]) 144 | if xor!=int(key_bin[i+7]): 145 | return False 146 | return True 147 | 148 | #密钥置换选择1 149 | def key_ds1(key): 150 | s='' 151 | for i in key_table1: 152 | s+=key[i] 153 | return s 154 | #密钥置换选择2 155 | def key_ds2(key): 156 | s='' 157 | for i in key_table2: 158 | s+=key[i] 159 | return s 160 | #密钥循环左移 161 | def key_move(key,r): 162 | # print('key=',key,'len=',len(key)) 163 | # s = key[l[r] : ] + key[ : l[r]][::-1] 164 | s=key 165 | for i in range(l[r]): 166 | s=s[1:]+s[:1] 167 | # print('s=',s,'len=',len(s)) 168 | return s 169 | #通过64位密钥获取全部的子密钥 170 | def get_subkey(key_bin): 171 | #首先进行key_bin的奇偶校验检查 172 | if check_key(key_bin)==False: 173 | print('密钥奇偶校验不通过!') 174 | return 175 | #print('密钥奇偶校验通过!') 176 | key=[] 177 | #密钥置换选择1 178 | key1_res=key_ds1(key_bin) 179 | # print(key1_res,len(key1_res)) 180 | L=key1_res[:28] 181 | R=key1_res[28:] 182 | # print('l=',L,len(L)) 183 | # print('r=',R,len(R)) 184 | for i in range(16): 185 | #循环左移 186 | L=key_move(L,i) 187 | R=key_move(R,i) 188 | #密钥置换选择2 189 | key.append(key_ds2(L+R)) 190 | # print('keys:') 191 | # for i in key: 192 | # print(i) 193 | #print('16轮子密钥成功生成!') 194 | # print('key=',key) 195 | return key 196 | 197 | #扩展置换E 198 | def extend_E(R): 199 | r='' 200 | for i in E: 201 | r+=R[i] 202 | return r 203 | #代换选择S盒 204 | def alter_s(t): 205 | j=0 206 | res='' 207 | for i in range(0,48,6): 208 | c=int(t[i+1:i+5],2) 209 | r=int(t[i]+t[i+5],2) 210 | res+='{:04b}'.format((sbox[j][r*16+c])) 211 | j+=1 212 | # print(res) 213 | return res 214 | #P置换 215 | def p_repl(s): 216 | p='' 217 | for i in P: 218 | p+=s[i] 219 | return p 220 | 221 | #DES加密基本函数,输入64位明文和密钥 222 | def DES(M,key): 223 | #首先将明文进行初始置换IP 224 | m='' 225 | for i in IP: 226 | m+=M[i] 227 | L=[] 228 | R=[] 229 | # print('m=',m) 230 | L.append(m[:32]) 231 | R.append(m[32:]) 232 | #16轮feistel结构 233 | for i in range(16): 234 | L.append(R[i]) 235 | #将R进行扩展置换E 236 | R_extend=extend_E(R[i]) 237 | #异或子密钥 K(i) 238 | #print('r=',R_extend) 239 | 240 | #优化算法 241 | # t='' 242 | # for j in range(48): 243 | # #print(R_extend[j],key[i][j]) 244 | # t+=str(int(R_extend[j])^int(key[i][j])) 245 | t='{:048b}'.format(int(R_extend,2)^int(key[i],2)) 246 | # print('t=',t) 247 | #代换选择S盒 248 | s=alter_s(t) 249 | # print('s=',s) 250 | #P置换 251 | p=p_repl(s) 252 | #异或L(i-1) 253 | # print('p=', p) 254 | 255 | #优化算法 256 | # r='' 257 | # for j in range(32): 258 | # r+=str(int(p[j])^int(L[i][j])) 259 | r='{:032b}'.format(int(p,2)^int(L[i],2)) 260 | R.append(r) 261 | # print('l+r',L[i] + R[i]) 262 | #左右交换 263 | c=R[16]+L[16] 264 | #逆初始置换 265 | cipher='' 266 | for i in IP_1: 267 | cipher+=c[i] 268 | return cipher 269 | 270 | #随机生成满足奇偶校验的64位密钥 271 | def get_rand_key(p): 272 | key_seed=os.urandom(8) #随机获取8个字符 273 | KEY_bin_str='' 274 | for i in key_seed: 275 | binstr='{:07b}'.format(i) #将每个字符转成7位二进制,第8位用于表示奇偶校验位 276 | xor=int(binstr[0])^int(binstr[1])^int(binstr[2])^int(binstr[3])^int(binstr[4])^int(binstr[5])^int(binstr[6]) 277 | for i in range(7): 278 | KEY_bin_str+=str(binstr[i]) 279 | KEY_bin_str+=str(xor) 280 | # print(binstr[0],binstr[1],binstr[2],binstr[3],binstr[4],binstr[5],binstr[6],sep=' ^ ',end=' = ') 281 | # print(xor) 282 | #print('随机生成的密钥',p,'为: ',KEY_bin_str,' ',len(KEY_bin_str),'位') 283 | # print(len(KEY_bin_str)) 284 | return KEY_bin_str 285 | 286 | #DES加密函数 287 | def DES_encrypt(message_bin_data,sub_key,i): 288 | #print(sub_key[0]) 289 | # print('正在利用密钥',i,'对数据进行DES加密') 290 | ciphertext=DES(message_bin_data,sub_key) 291 | # print('加密后得到的二进制流为:',ciphertext,' ',len(ciphertext),'位') 292 | return ciphertext 293 | 294 | #DES解密函数 295 | def DES_decrypt(ciphertext,key,i): 296 | # print('正在利用密钥',i,'对数据进行DES解密') 297 | plainbin=DES(ciphertext,key) 298 | # print('解密后得到的二进制流为:',plainbin,' ',len(plainbin),'位') 299 | return plainbin 300 | 301 | #进行二重DES加密 302 | def DES_2_encrypt(s,sub_key1,sub_key2): 303 | # print("*** 开始进行二重DES加密 ***") 304 | #print("*** 正在随机生成DES密钥 ***") 305 | # print("*** 正在进行二重DES加密 ***") 306 | ciphertext=DES_encrypt(s,sub_key1,1) 307 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 308 | return ciphertext 309 | def DES_2_decrypt(ciphertext,sub_key1,sub_key2): 310 | # print("*** 正在进行二重DES解密 ***") 311 | sub_key1=sub_key1[::-1] 312 | sub_key2=sub_key2[::-1] 313 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 314 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 315 | return plaintext 316 | 317 | #三重DES加密 318 | def DES_3_encrypt(s,sub_key1,sub_key2,sub_key3): 319 | #print(sub_key1[0]) 320 | sub_key2=sub_key2[::-1] #解密密钥 321 | # print("*** 正在进行三重DES加密 ***") 322 | ciphertext=DES_encrypt(s,sub_key1,1) 323 | ciphertext=DES_decrypt(ciphertext,sub_key2,2) 324 | ciphertext=DES_encrypt(ciphertext,sub_key3,3) 325 | return ciphertext 326 | #三重DES解密 327 | def DES_3_decrypt(ciphertext,sub_key1,sub_key2,sub_key3): 328 | # print("*** 正在进行三重DES解密 ***") 329 | sub_key1=sub_key1[::-1] 330 | sub_key2=sub_key2 #加密密钥 331 | sub_key3=sub_key3[::-1] 332 | ciphertext=DES_decrypt(ciphertext,sub_key3,3) 333 | ciphertext=DES_encrypt(ciphertext,sub_key2,2) 334 | plaintext=DES_decrypt(ciphertext,sub_key1,1) 335 | # print("*** 三重DES解密成功 ***") 336 | return plaintext 337 | 338 | ############################################################ 339 | # # 340 | # *结束引用* # 341 | # # 342 | ############################################################ 343 | #获取明文的全部分组 344 | def get_group(filename): 345 | group_list=[] 346 | f=open(filename,'r') 347 | for line in f: 348 | group_list.append(line.strip('\n')) 349 | f.close() 350 | return group_list 351 | #获取初始IV向量 352 | def get_IV(): 353 | iv_seed=os.urandom(8) #随机获取8个字符 354 | iv_bin_str='' 355 | for i in iv_seed: 356 | iv_bin_str+='{:08b}'.format(i) 357 | return iv_bin_str 358 | #CBC加密 359 | def CBC_encrypt(group_list,iv,key_bin1,key_bin2,key_bin3): 360 | print("*** 正在获取子密钥 ***") 361 | sub_key1=get_subkey(key_bin1) 362 | sub_key2=get_subkey(key_bin2) 363 | sub_key3=get_subkey(key_bin3) 364 | C_list=[] 365 | Iv=iv 366 | print("*** 正在进行CBC加密 ***") 367 | for group in group_list: 368 | xor_res='' 369 | # for i in range(64): 370 | # xor_res+=str(int(group[i])^int(Iv[i])) 371 | #优化算法 372 | xor_res='{:064b}'.format(int(group,2)^int(Iv,2)) 373 | C=DES_3_encrypt(xor_res,sub_key1,sub_key2,sub_key3) 374 | C_list.append(C) 375 | Iv=C 376 | return C_list 377 | #CBC解密 378 | def CBC_decrypt(C_list,iv,key_bin1,key_bin2,key_bin3): 379 | sub_key1=get_subkey(key_bin1) 380 | sub_key2=get_subkey(key_bin2) 381 | sub_key3=get_subkey(key_bin3) 382 | P_list=[] 383 | Iv=iv 384 | for c in C_list: 385 | res=DES_3_decrypt(c,sub_key1,sub_key2,sub_key3) 386 | xor_res='' 387 | # for i in range(64): 388 | # xor_res+=str(int(res[i])^int(Iv[i])) 389 | #优化算法,加快运算速度 390 | xor_res='{:064b}'.format(int(res,2)^int(Iv,2)) 391 | P_list.append(xor_res) 392 | Iv=c 393 | return P_list 394 | #存储加密后的分组信息 395 | def save_img_data(filename,list_data): 396 | f=open(filename,'w') 397 | for i in list_data: 398 | f.write(i+'\n') 399 | f.close() 400 | 401 | def save_iv_data(filename,iv): 402 | f=open(filename,'w') 403 | f.write(iv+'\n') 404 | f.close() 405 | 406 | def save_keys(filename,key_bin1,key_bin2,key_bin3): 407 | f=open(filename,'w') 408 | f.write(key_bin1+'\n') 409 | f.write(key_bin2+'\n') 410 | f.write(key_bin3+'\n') 411 | f.close() 412 | 413 | from PIL import Image 414 | #获取图像的宽高 415 | def get_img_inf(img): 416 | im = Image.open(img) 417 | return im.size[0],im.size[1] 418 | #获取加密后的像素信息 419 | def get_img_data(filename): 420 | img_data='' 421 | f=open(filename,'r') 422 | for line in f: 423 | img_data+=(line.strip('\n')) 424 | f.close() 425 | return img_data 426 | #绘制加密后的图像 427 | def draw_image(img_data,img_filename,img_width,img_height): 428 | img = Image.new('RGB',(img_width,img_height)) 429 | c=0 430 | for i in range(img_width): 431 | for j in range(img_height): 432 | r=int(img_data[c:c+8],2) 433 | g=int(img_data[c+8:c+16],2) 434 | b=int(img_data[c+16:c+24],2) 435 | # print('绘制加密图片',i,j,r,g,b,sep=' ') 436 | img.putpixel((i,j),(r,g,b)) 437 | c+=24 438 | img.save(img_filename) 439 | 440 | 441 | #获取密钥信息函数 442 | def get_keys(filename): 443 | f=open(filename,'r') 444 | keys=[] 445 | for line in f: 446 | keys.append(line.strip('\n')) 447 | return keys[0],keys[1],keys[2] 448 | #获取iv信息 449 | def get_iv(filename): 450 | f=open(filename,'r') 451 | return f.readline().strip('\n') 452 | #获取加密图像的像素信息 453 | def get_img_data(filename): 454 | img_data='' 455 | f=open(filename,'r') 456 | for line in f: 457 | img_data+=(line.strip('\n')) 458 | f.close() 459 | return img_data 460 | #绘制解密图像信息 461 | def draw_image(img_data,img_filename,img_width,img_height): 462 | img = Image.new('RGB',(img_width,img_height)) 463 | c=0 464 | for i in range(img_width): 465 | for j in range(img_height): 466 | r=int(img_data[c:c+8],2) 467 | g=int(img_data[c+8:c+16],2) 468 | b=int(img_data[c+16:c+24],2) 469 | # print('绘制加密图片',i,j,r,g,b,sep=' ') 470 | img.putpixel((i,j),(r,g,b)) 471 | c+=24 472 | img.save(img_filename) 473 | 474 | 475 | 476 | def main(): 477 | #需要转换为01比特序列的图片名 478 | img_dir="original_img.png" 479 | #获取图像的像素点 480 | print("*** 正在获取图像信息 ***") 481 | bin_data,img_width,img_height=get_pixel(img_dir) 482 | print('图像宽度:',img_width,'图像高度:',img_height) 483 | bin_data_list=set_group(bin_data) 484 | save_group_data(bin_data_list) 485 | print("*** 保存明文分组信息成功 ***") 486 | print("*** 明文分组信息存储在group.txt文件中 ***") 487 | # print("最终获取的明文分组为:",bin_data_list) 488 | #明文分组文件名 489 | group_file_name='group_data.txt' 490 | #获取分组列表 491 | group_list = get_group(group_file_name) 492 | #获取初始向量IV 493 | iv=get_IV() 494 | #随机生成3个DES密钥 495 | key_bin1=get_rand_key(1) 496 | key_bin2=get_rand_key(2) 497 | key_bin3=get_rand_key(3) 498 | #进行CBC模型下的三重DES加密 499 | c_list=CBC_encrypt(group_list,iv,key_bin1,key_bin2,key_bin3) 500 | #CBC模型下的三重DES解密 501 | #p_list=CBC_decrypt(c_list,iv,key_bin1,key_bin2,key_bin3) 502 | #保存加密后分组数据便于 4密文图像显示 503 | save_img_data('encrypt_data.txt',c_list) 504 | #保存初始向量IV信息用于解密 505 | save_iv_data('iv.txt',iv) 506 | #保存解密数据 507 | #save_data('decrypt_data.txt',p_list) 508 | #保存密钥信息 509 | save_keys('keys.txt',key_bin1,key_bin2,key_bin3) 510 | print("*** 相关信息保存成功! ***") 511 | ori_img='original_img.png' 512 | img_width,img_height=get_img_inf(ori_img) 513 | #通过加密后的分组信息绘制密文图像 514 | filename='encrypt_data.txt' 515 | img_data=get_img_data(filename) 516 | img_filename='encrypted_img.png' 517 | draw_image(img_data,img_filename,img_width,img_height) 518 | print('绘制加密图片成功!') 519 | print('*** 正在进行密文图像解密 ***') 520 | #加密图像 521 | enc_img='encrypted_img.png' 522 | #密钥文件 523 | keys_file='keys.txt' 524 | #iv文件 525 | iv_file='iv.txt' 526 | #获取加密后图像的像素值和宽高 527 | bin_data,img_width,img_height=get_pixel(enc_img) 528 | print('*** 获取加密图像数据成功! ***') 529 | #获取密钥信息 530 | key_bin1,key_bin2,key_bin3=get_keys(keys_file) 531 | print('*** 获取密钥信息成功! ****') 532 | #获取初始向量IV 533 | iv=get_iv(iv_file) 534 | #对加密数据进行分组 535 | bin_data_list=set_group(bin_data) 536 | #获取解密的分组信息 537 | p_list=CBC_decrypt(bin_data_list,iv,key_bin1,key_bin2,key_bin3) 538 | img_data=''.join(p_list) 539 | img_filename='decrypted_img.png' 540 | #绘制解密图像 541 | draw_image(img_data,img_filename,img_width,img_height) 542 | print('绘制解密图片成功!') 543 | 544 | 545 | if __name__ == '__main__': 546 | main() 547 | 548 | 549 | 550 | 551 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### **基于DES的数字图像加密算法的设计与实现** 2 | 3 | DES填充模式:PKCS#5 4 | 5 | 选用三重DES进行加密 6 | 7 | 选用密码分组链接(CBC)模式作为DES运行模式 8 | 9 | 按照序号顺序运行文件即可正确的对图像进行加解密 10 | 11 | 文件运行顺序: 12 | 13 | 1数字图像的处理.py 14 | 2组内加密.py 15 | 3分组运行模式.py 16 | 4密文图像显示.py 17 | 5密文图像解密.py 18 | 19 | 或者 20 | 直接运行 6三重DES和CBC分组加密实现.py 21 | 22 | 文件说明: 23 | 24 | 原始图像:original_img.png 25 | 原始分组信息:group_data.txt 26 | DES密钥信息:keys.txt 27 | 初始向量IV信息:iv.txt 28 | 加密后的分组信息:encrypt_data.txt 29 | 加密后的图像:encrypted_img.png 30 | 解密后的图像:decrypted_img.png 31 | 32 | 33 | *注意* 34 | 35 | 1.由于DES密钥和IV向量每次都是随机生成的,请按照指定代码文件顺序运行代码或直接运行6三重DES和CBC分组加密实现.py 36 | 37 | 2.初始加密时仅需保留原始图像:original_img.png和代码文件,其余文件均为程序运行时自动生成的文件 38 | 39 | 3.请使用python3运行代码,同时确保相应的库文件已经正确安装 40 | 41 | 42 | 43 | 44 | **Design and implementation of digital image encryption algorithm based on DES** 45 | 46 | DES Fill Mode: PKCS # 5 47 | 48 | Triple DES encryption 49 | 50 | Select password block link (CBC) mode as DES operation mode 51 | 52 | Run the file in the sequence of serial number to correctly encrypt and decrypt the image 53 | 54 | File running order: 55 | 56 | 1数字图像的处理.py 57 | 2组内加密.py 58 | 3分组运行模式.py 59 | 4密文图像显示.py 60 | 5密文图像解密.py 61 | perhaps 62 | 63 | Directly run 6三重DES和CBC分组加密实现.py 64 | 65 | Document description: 66 | 67 | Original image: original_ img.png 68 | 69 | Original group information: group_ data.txt 70 | 71 | DES key information: keys.txt 72 | 73 | Initial vector IV information: iv.txt 74 | 75 | Encrypted packet information: encrypt_ data.txt 76 | 77 | Encrypted image: encrypted_ img.png 78 | 79 | Decrypted image: decrypted_ img.png 80 | 81 | *Attention* 82 | 83 | 1. Since the DES key and IV vector are randomly generated each time, please run the code in the order of the specified code file or directly run 6三重DES和CBC分组加密实现.py 84 | 85 | 2. During initial encryption, only the original image: original_ Img.png and code files, and other files are automatically generated when the program runs 86 | 87 | 3. Please use python 3 to run the code and ensure that the corresponding library files have been installed correctly 88 | 89 | (●'◡'●) 90 | -------------------------------------------------------------------------------- /decrypted_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MonsterFanSec/Digital-Image-Encryption-Algorithm-Based-on-DES/1aa2790425818ba1b53c428f70d577215a2db718/decrypted_img.png -------------------------------------------------------------------------------- /encrypted_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MonsterFanSec/Digital-Image-Encryption-Algorithm-Based-on-DES/1aa2790425818ba1b53c428f70d577215a2db718/encrypted_img.png -------------------------------------------------------------------------------- /iv.txt: -------------------------------------------------------------------------------- 1 | 1100011111100111001101101001101110110010111010010110000101010111 2 | -------------------------------------------------------------------------------- /keys.txt: -------------------------------------------------------------------------------- 1 | 1001001111001111111001000111000100101000101100011100001101010101 2 | 1000000111001111110100011111110011111010100010001001100110010000 3 | 1011000111011000100010001001011010000001101101001011000101011100 4 | -------------------------------------------------------------------------------- /original_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MonsterFanSec/Digital-Image-Encryption-Algorithm-Based-on-DES/1aa2790425818ba1b53c428f70d577215a2db718/original_img.png -------------------------------------------------------------------------------- /说明.txt: -------------------------------------------------------------------------------- 1 | DES填充模式:PKCS#5 2 | 选用三重DES进行加密 3 | 选用密码分组链接(CBC)模式作为DES运行模式 4 | 按照序号顺序运行文件即可正确的对图像进行加解密 5 | 文件运行顺序: 6 | 1数字图像的处理.py 7 | 2组内加密.py 8 | 3分组运行模式.py 9 | 4密文图像显示.py 10 | 5密文图像解密.py 11 | 或者 12 | 直接运行 6三重DES和CBC分组加密实现.py 13 | 文件说明: 14 | 原始图像:original_img.png 15 | 原始分组信息:group_data.txt 16 | DES密钥信息:keys.txt 17 | 初始向量IV信息:iv.txt 18 | 加密后的分组信息:encrypt_data.txt 19 | 加密后的图像:encrypted_img.png 20 | 解密后的图像:decrypted_img.png 21 | *注意* 22 | 1.由于DES密钥和IV向量每次都是随机生成的,请按照指定代码文件顺序运行代码或直接运行6三重DES和CBC分组加密实现.py 23 | 2.初始加密时仅需保留原始图像:original_img.png和代码文件,其余文件均为程序运行时自动生成的文件 24 | 3.请使用python3运行代码,同时确保相应的库文件已经正确安装 25 | --------------------------------------------------------------------------------