modern-crypto-system
现代密码加解密系统,自行设计的基于Feistel结构的分组密码+AES对称密码+RSA非对称密码,python实现
分组密码
自行设计的基于Feistel结构的分组密码,包含有雪崩效应分析。
采用的轮函数为异或,对于函数为简单的异或函数的feistel网络来说,难以达到雪崩效应的要求(50%以上),但是随着加密轮次的提升,雪崩效应也越来越大。
效果演示
雪崩效应分析:给出一个随机的输入,改变1比特后,追踪所有各处理环节及轮次改变的比特数量比例
代码
# -*- coding: utf-8 -*-
# 每个分组8个字符,一个密钥4个字符
def strEncrypt(s1, s2, key): # 每次传输8个字符,分成两组按位异或,密钥4个字符
result = ''
for i in range(0, 4):
temp = ord(s1[i]) ^ ord(s2[i]) ^ ord(key[i])
result += chr(temp)
return result
def encode(plainText1,plainText2, keylist):
cipherText1 = ''
cipherText2 = ''
for i in range(0, len(plainText1) // 8):
temp1 = plainText1[i * 8:(i + 1) * 8] # 每8个字符划分成一组加密
L1 = temp1[:4]
R1 = temp1[4:]
temp2 = plainText2[i * 8:(i + 1) * 8] # 每8个字符划分成一组加密
L2 = temp2[:4]
R2 = temp2[4:]
j = 1
for currentKey in keylist:
temp11 = R1
R1 = strEncrypt(L1, R1, currentKey)
L1 = temp11
tempText1 = ""
tempText1 += R1 + L1
print("********************第%d轮***************************"%j)
print("明文1第%d轮加密后序列为:%s"%(j,tempText1))
temp22 = R2
R2 = strEncrypt(L2, R2, currentKey)
L2 = temp22
tempText2 = ""
tempText2 += R2 + L2
print("明文2第%d轮加密后序列为:%s" % (j, tempText2))
num = count(tempText1,tempText2)
print("改变比特的数量:%d"%num)
print("雪崩效应:%f"%(num/len(tempText1)))
j += 1
cipherText1 += R1 + L1
cipherText2 += R2 + L2
return [cipherText1,cipherText2]
def count(m, n):
count = 0
index = 0
for a in m:
if a != n[index]:
count+=1
index+=1
return count
def main():
key = []
a = input('请输入明文:')
b = input('请输入改变一个比特明文:')
keynum = input('请输入加密循环次数:')
for i in range(0, int(keynum)):
temp = input('请输入第' + str(i) + '组加密时使用的密钥(4个字符)')
key.append(temp)
[a,b] = encode(a,b, key)
print('最终密文1:', a)
print('最终密文2:', b)
#####解密
# key.reverse()
# a = encode(a, key)
# print('解密后的明文:', a)
if __name__ == '__main__':
main()
AES分组密码
流程图
效果演示
代码
import os, random, struct
from Crypto.Cipher import AES
try:
from Crypto.Util.Padding import pad, unpad
except ImportError:
from Crypto.Util.py3compat import bchr, bord
def pad(data_to_pad, block_size):
padding_len = block_size-len(data_to_pad)%block_size
padding = bchr(padding_len)*padding_len
return data_to_pad + padding
def unpad(padded_data, block_size):
pdata_len = len(padded_data)
if pdata_len % block_size:
raise ValueError("Input data is not padded")
padding_len = bord(padded_data[-1])
if padding_len<1 or padding_len>min(block_size, pdata_len):
raise ValueError("Padding is incorrect.")
if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:
raise ValueError("PKCS#7 padding is incorrect.")
return padded_data[:-padding_len]
def encrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
if not out_filename:
out_filename = in_filename + '.enc'
iv = os.urandom(16)
encryptor = AES.new(key, AES.MODE_CBC, iv)
filesize = os.path.getsize(in_filename)
with open(in_filename, 'rb') as infile:
with open(out_filename, 'wb') as outfile:
outfile.write(struct.pack('<Q', filesize))
outfile.write(iv)
pos = 0
while pos < filesize:
chunk = infile.read(chunksize)
pos += len(chunk)
if pos == filesize:
chunk = pad(chunk, AES.block_size)
outfile.write(encryptor.encrypt(chunk))
def decrypt_file(key, in_filename, out_filename=None, chunksize=64*1024):
if not out_filename:
out_filename = in_filename + '.dec'
with open(in_filename, 'rb') as infile:
filesize = struct.unpack('<Q', infile.read(8))[0]
iv = infile.read(16)
encryptor = AES.new(key, AES.MODE_CBC, iv)
with open(out_filename, 'wb') as outfile:
encrypted_filesize = os.path.getsize(in_filename)
pos = 8 + 16 # the filesize and IV.
while pos < encrypted_filesize:
chunk = infile.read(chunksize)
pos += len(chunk)
chunk = encryptor.decrypt(chunk)
if pos == encrypted_filesize:
chunk = unpad(chunk, AES.block_size)
outfile.write(chunk)
#测试代码
if __name__=='__main__':
# key = "keyskeyskeyskeys"
print("******************欢迎来到离线内容保护系统**********************")
while True:
print("1、AES加密文件 2、AES解密文件 3、退出系统")
chioce = input("请选择对应功能的序号:")
if chioce == "1":
print("AES加密开始!")
file = input("请输入要加密的文件的路径+文件名:")
key = input("请输入加密密钥:")
encrypt_file(key.encode('utf-8'),file)
print("加密成功!加密后的文件为"+file+".enc")
print("***************************************************")
elif chioce == "2":
print("AES解密开始!")
file = input("请输入要解密的文件的路径+文件名:")
key = input("请输入解密密钥:")
decrypt_file(key.encode('utf-8'), file)
print("解密成功!解密后的文件为" + file + ".dec")
print("***************************************************")
elif chioce == "3":
print("退出成功,拜拜~~")
break
else:
print("错误!请输入1、2、3中的一个")
RSA非对称密码
流程图
效果演示
代码
from OpenSSL.crypto import PKey
from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM
from OpenSSL.crypto import dump_privatekey, dump_publickey
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
import os,rsa
from rsa import VerificationError
def generate_key():
pk = PKey()
pk.generate_key(TYPE_RSA, 2048)
# 生成公钥文件
public_key = dump_publickey(FILETYPE_PEM, pk)
public_key_path = os.path.join(os.path.dirname(__file__), 'public_key.pem')
file_public_key = open(public_key_path, 'wb')
file_public_key.write(public_key)
file_public_key.close()
# 生成私钥文件
private_key = dump_privatekey(FILETYPE_PEM, pk)
private_key_path = os.path.join(os.path.dirname(__file__), 'private_key.pem')
file_private_key = open(private_key_path, 'wb')
file_private_key.write(private_key)
file_private_key.close()
# 加密文件
def encrypt_file(key_file_name, file_path):
key_file = open(key_file_name, 'rb')
key_data = key_file.read()
key_file.close()
public_key = serialization.load_pem_public_key(key_data, backend=default_backend())
file = open(file_path, 'rb')
file_data = file.read()
encrypt_file_data = public_key.encrypt(file_data, padding.PKCS1v15())
encrypt_file_path = file_path + ".enc"
encrypt_file = open(encrypt_file_path, 'wb')
encrypt_file.write(encrypt_file_data)
encrypt_file.close()
# 解密文件
def decrypt_file(key_file_name, file_path):
key_file = open(key_file_name, 'rb')
key_data = key_file.read()
key_file.close()
private_key = serialization.load_pem_private_key(key_data, password=None,backend=default_backend())
file = open(file_path, 'rb')
file_data = file.read()
decrypt_file_data = private_key.decrypt(file_data,padding.PKCS1v15())
decrypt_file_path = file_path + ".dec"
decrypt_file = open(decrypt_file_path, 'wb')
decrypt_file.write(decrypt_file_data)
decrypt_file.close()
if __name__=='__main__':
print("**********************************欢迎来到SSL文件加解密系统************************************")
while True:
print("1、生成RSA公钥和私钥 2、RSA公钥加密文件 3、RSA私钥解密文件 4、退出系统")
chioce = input("请选择对应功能的序号:")
if chioce == "1":
print("生成RSA公钥和私钥开始!")
generate_key()
print("生成RSA公钥和私钥成功!")
print("生成的RSA公钥文件在当前程序目录下,文件名为:public_key.pem")
print("生成的RSA私钥文件在当前程序目录下,文件名为:private_key.pem")
print("****************************************************************************")
elif chioce == "2":
print("RSA公钥加密开始!")
file = input("请输入要加密的文件的路径+文件名:")
key = input("请输入RSA公钥的文件的路径+文件名:")
encrypt_file(key, file)
print("加密成功!加密后的文件为:"+file+".enc")
print("****************************************************************************")
elif chioce == "3":
print("RSA私钥解密开始!")
file = input("请输入要解密的文件的路径+文件名:")
key = input("请输入RSA私钥的文件的路径+文件名:")
decrypt_file(key, file)
print("解密成功!解密后的文件为:" + file + ".dec")
print("****************************************************************************")
elif chioce == "4":
print("退出成功,拜拜~~")
break
else:
print("错误!请输入1、2、3、4中的一个")