RSA,AES加解密算法的实现

Python实现RSA公钥加密算法

RSA公钥加密算法原理

1、RSA公钥加密算法属于非对称密码,因此有一对密钥,公钥和私钥,Ron Rivest, Adi Shamir和Len Adleman于1977年研制并于1978年首次发表;

2、RSA是一种分组密码,其理论基础是一种特殊的可逆模幂运算,其安全性基于分解大整数的困难性,即将两个大素数相乘非常容易,但是想对其乘积进行因式分解是十分困难的,因此将其乘积公开作为加密密钥(公钥)

3、对一个极大的整数做因数分解愈困难,RSA算法越可靠;

4、RSA既可用于加密,又可用于数字签名,已得到广泛采用;

5、RSA加解密过程图解如下:

6、RSA算法流程:

RSA算法的Python实现

PS:求幂次的模拟(mod)为平方乘的方法进行计算,未调用Python中的RSA包

1、程序如下:

import random
import binascii
import argparse  # 导入读取命令行参数的模块
import sys

sys.setrecursionlimit(100000)  # 设置迭代次数限制

def main():
    Build_key()  # 生成公钥、密钥

    parser = argparse.ArgumentParser(
        description="This is a description, it includes the whole file's loactions of RSA algorithm.")
    parser.add_argument('-p', required=True, type=argparse.FileType('r'), help='plainfile')
    parser.add_argument('-n', required=True, type=argparse.FileType('r'), help='nfile')
    parser.add_argument('-e', required=False, type=argparse.FileType('r'), help='efile')  # e,d文件不是都要的,只需一个
    parser.add_argument('-d', required=False, type=argparse.FileType('r'), help='dfile')
    parser.add_argument('-c', required=True, type=argparse.FileType('w+'), help='cipherfile')
    args = parser.parse_args()  # args里面的成员是一个文件对象,所以后面写入文件的形式和一般的一样
    n = int(args.n.read(), 16)
    m = args.p.read()

    if m == '':
        print('No PlainText!')
    else:
        print("Encrypting......")
        e = int(args.e.read(), 16)
        cipher = encrypt(m, e, n)

        with args.c as f:
            f.write(cipher)
        print("Encrypted!\r\nThe Cipher is:", cipher)

    c = cipher  # 读取密文
    if c == '':
        print("No Cipher!")
    else:
        print("Decrypting......")
        d = int(args.d.read(), 16)
        plain = decrypt(c, d, n)

        print("Decrypted!\r\nThe PlainText is:", plain)


# 平方—乘法,最后返回结果
def MRF(b, n, m):
    a = 1

    x = b
    y = n
    z = m

    binstr = bin(n)[2:][::-1]  # 通过切片去掉开头的0b,截取后面,然后反转

    for item in binstr:
        if item == '1':
            a = (a * b) % m
            b = (b ** 2) % m

        elif item == '0':
            b = (b ** 2) % m

    return a


# 素性检验

def MillerRabin(n):
    "利用Miller-Rabin算法检验生成的奇数是否为素数"

    m = n - 1
    k = 0
    while (m % 2 == 0):
        m = m // 2 #m整除2
        k = k + 1
    a = random.randint(2, n)#生成随机数2<=a<=n
    # b=a**m%n
    b = MRF(a, m, n) #快速乘进行检验

    if (b == 1):
        return 1
    for i in range(k):
        if (b == n - 1):
            return 1
        else:
            b = b * b % n
    return 0


# 生成大素数,20次MillerRabin算法缩小出错的概率
def BigPrime():
    Min = 10 ** 11 #**幂运算
    Max = 10 ** 15
    p = 0

    while (1):
        p = random.randrange(Min, Max, 1)#寻找min和max中的随机数p
        #生成大素数p
        for i in range(20):
            if MillerRabin(p) == 0:
                break
            elif i == 19:
                return p


# 加密,传入公钥,通过读取明文文件进行加密
def encrypt(m, e, n):
    cipher = ""
    nlength = len(str(hex(n))[2:])  # 计算n的16进制长度,以便分组
    message = m  # 读取明文

    for i in range(0, len(message), 8):#8个字节为一组
        if i == len(message) // 8 * 8:
            m = int(a2hex(message[i:]), 16)  # 最后一个分组

        m = int(a2hex(message[i:i + 8]), 16)
        c = MRF(m, e, n)
        cipher1 = str(hex(c))[2:]

        if len(cipher1) != nlength:
            cipher1 = '0' * (nlength - len(cipher1)) + cipher1  # 每一个密文分组,长度不够,高位补0
        cipher += cipher1

    return cipher


# 解密,传入私钥,通过文件读写进行解密
def decrypt(c, d, n):
    # 加密之后每一个分组的长度和n的长度相同
    cipher = c
    message = ""
    nlength = len(str(hex(n))[2:])

    for i in range(0, len(cipher), nlength):
        c = int(cipher[i:i + nlength], 16)  # 得到一组密文的c

        m = MRF(c, d, n)
        info = hex2a(str(hex(m))[2:])
        message += info

    f_write("RSA_decrypted.txt", message)
    return message


# 求最大公因子
def gcd(a, b):
    if a % b == 0:
        return b
    else:
        return gcd(b, a % b)


# 求逆元欧几里得辗转相乘法计算逆
def Ex_Euclid(x, n):
    r0 = n
    r1 = x % n

    if r1 == 1:
        y = 1
    else:
        s0 = 1
        s1 = 0
        t0 = 0
        t1 = 1

        while (r0 % r1 != 0):
            q = r0 // r1
            r = r0 % r1
            r0 = r1
            r1 = r
            s = s0 - q * s1
            s0 = s1
            s1 = s
            t = t0 - q * t1
            t0 = t1
            t1 = t

            if r == 1:
                y = (t + n) % n
    return y


# 写入文件
def f_write(filename, message):
    f = open(filename, 'w')
    f.write(message)
    f.close()

    return 0


# ascii_to_hex
def a2hex(raw_str):
    hex_str = ''
    for ch in raw_str:
        hex_str += hex(ord(ch))[2:]

    return hex_str


# hex_to_ascii
def hex2a(raw_str):
    asc_str = ''

    for i in range(0, len(raw_str), 2):
        asc_str += chr(int(raw_str[i:i + 2], 16))

    return asc_str


def Build_key():
    # 产生p,q,n,e,d
    p = BigPrime()
    q = BigPrime()
    n = p * q
    _n = (p - 1) * (q - 1)  # n的欧拉函数
    e = 0

    while (1):
        e = random.randint(1, _n + 1)
        if gcd(e, _n) == 1:
            break

    d = Ex_Euclid(e, _n)
    # 写入文件
    f_write('p.txt', str(hex(p))[2:])
    f_write('q.txt', str(hex(q))[2:])
    f_write('n.txt', str(hex(n))[2:])
    f_write('e.txt', str(hex(e))[2:])
    f_write('d.txt', str(hex(d))[2:])


if __name__ == "__main__":
    main()
 

2、运行截图

3、加解密文件

AES加解密算法实现

AES加解密算法原理

1、AES算法由比利时密码学家Joan Daemen 和 Vincent Rijmen 提出;

2、AES算法的原型是Square算法,其设计策略是宽轨迹策略(Wide Trail Strategy),以针对差分分析和线性分析;

3、AES是迭代分组密码,其分组长度和密钥长度都是可变的;为了满足AES的要求,分组长度为128bit,密码长度为128/192/256bit,相应的轮数r为10/12/14;

4、算法流程图:

AES加解密算法Python实现

1、Python代码如下(PS:AES的实现是调用的Python中的AES包实现)

from Crypto.Cipher import AES
from binascii import b2a_hex
from binascii import a2b_hex
import sys
import binascii

def encrypt(plain, iv, key):
    if len(key) != 16 and len(key) != 24 and len(key) != 32:
        print("[-] AES key must be 16/24/32 bytes long!")
        return False
    key = key.encode('utf8')
    iv = iv.encode('utf8')
    cryptos = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cryptos.encrypt(plain.encode('utf8'))
    return ciphertext

def decrypt(ciphertext, iv, key):

    key = key.encode('utf8') #string->bytes
    iv = iv.encode('utf8')
    decrypto = AES.new(key, AES.MODE_CBC, iv)
    plaintext = decrypto.decrypt(ciphertext)

    return plaintext


if __name__ == "__main__":
    plain = 'AESPython_Jody23'
    iv = '12345678dc123478'
    key = '0CoJUm6Qyw8W8jud'
    ciphertext = encrypt(plain,iv,key)
    print("Encrypt: ")
    print(ciphertext)
    plaintext = decrypt(ciphertext,iv,key)
    print("Decrypt: ")
    print(plaintext.decode('utf8'))

2、运行截图

参考文献

原文地址:https://www.cnblogs.com/Jody9123/p/12485715.html