zoukankan      html  css  js  c++  java
  • 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、运行截图

    参考文献

  • 相关阅读:
    javascript DOM事件总结
    MySQL索引优化实例说明
    CSV导出大量数据
    最详细的PHP flush()与ob
    XSS攻击(跨站攻击)
    MySQL视图
    MySQL索引
    待整理
    Height、clientHeight、scrollHeight、offsetHeight 、scrollTop、offsetTop
    Cookie和Session的区别
  • 原文地址:https://www.cnblogs.com/Jody9123/p/12485715.html
Copyright © 2011-2022 走看看