现代密码加解密

Hello World, Hello crypto

Posted by Resulte on June 18, 2020

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中的一个")