RSA算法知识详解与验证__文章2

import math
import random
from sympy import isprime  # 判断是否素数


def prime_random(start, end):
    # 产生质数,范围max(start, end) < 2^64
    prime_number_list = []
    for prime_number in range(start, end):
        if isprime(prime_number):  # 如果是素数, 加入列表
            prime_number_list.append(prime_number)
    if not prime_number_list or max(start, end) > 2 ** 64:
        print("没有找到质数,返回13")
        return 13
    return random.choice(prime_number_list)  # 从列表随机取一个素数


def euler_phi(number):
    # 概念:欧拉函数在数论,对正整数n,欧拉函数φ(n)是小于n的正整数中与n互质的数的数目,以φ(n)表示欧拉函数
    # 在1—10中,与10互质的有1、3、7、9,即φ(10)=4。
    euler_num = 0
    for i in range(1, number):
        if math.gcd(i, number) == 1:
            euler_num += 1
    return euler_num


def RSA_Verification_testing():  # RSA 验证过程
    # RSA 看百度百科的算法描述即可: https://baike.baidu.com/item/RSA%E7%AE%97%E6%B3%95/263310?fromtitle=RSA&fromid=210678&fr=aladdin
    # RSA密钥 (PublicKey(n, e), PrivateKey(n, e, d, p, q))
    # 1.任意选取两个不同的大素数(质数)p和q, 计算乘积 n = pq, 注意p与q不能相等
    # 概念:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
    p = prime_random(7, 1024)  # 获取一个随机质数
    q = prime_random(13, 1024)  # 获取一个随机质数
    while p == q:
        p = 7  # 7
        q = 13  # 13
    print(f"质数:p:{p},q:{q}")
    n = p * q  # 91
    print(f"模长n:{n}")

    # 2.计算n的欧拉函数φ(n), https://blog.51cto.com/u_15400016/4287468
    # 概念:欧拉函数在数论,对正整数n,欧拉函数φ(n)是小于n的正整数中与n互质的数的数目,以φ(n)表示欧拉函数
    # 在1—10中,与10互质的有1、3、7、9,即φ(10)=4。
    # 如果n是质数,则φ(n)=n-1 。因为质数与小于它的每一个数,都构成互质关系。比如7与1、2、3、4、5、6都构成互质关系,φ(7) = 7-1。
    # 由互质关系能得出以下结论:n = p1 × p2,则φ(n) = φ(p1p2) = φ(p1)φ(p2)=(p1-1)*(p2 -1) , φ(n) = φ(p1p2) = φ(3)φ(7)=2*6=12
    # print(euler_phi(21))   # euler_phi欧拉函数
    fn = (p - 1) * (q - 1)  # 72

    # 3.任意选取一个大整数e(公钥),满足gcd(e, φ(n)) = 1;整数e用做加密钥(注意:e的选取是很容易的,例如,所有大于p和q的素数都可用, 实际应用通常取65537)
    # 概念:最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个,如(12,15,18)=3
    for e in range(max(p, q) + 1, n):
        if math.gcd(e, fn) == 1:  # Python math.gcd() 方法返回给定的整数参数的最大公约数
            break
    print(f"公钥e:{e}, 是否素数{isprime(e)}")

    # 4.确定解密密钥d(私钥),满足(d*e) mod φ(n) = 1 (或d*e = k*φ(n) + 1, k为k≥1的任意整数)
    for d in range(int((fn+1)/e), n):
        if (d * e) % fn == 1:
            break
    print(f"私钥d:{d}, 是否素数{isprime(d)}")

    # 5.加密算法c = E(m) = m**e mod n,使用公钥 e 对明文 m 进行加密-----公钥加密(注意 m 需小于 n )
    m = random.randint(1, n - 1)
    print(f"明文:{m}")
    em = (m ** e) % n  # 加密
    print(f"公钥e加密:{em}")

    # 6.解密算法m = D(c) = c**d mod n, 使用私钥 d 对密文 em 进行解密-----私钥解密
    dm = (em ** d) % n  # 解密
    print(f"私钥d解密:{dm}")
    if m != dm:
        print("数据对比错误,(PublicKey(n, e), PrivateKey(n, e, d, p, q))")
        return {"m": m, "em": em, "dm": dm, "n": n, "e": e, "d": d, "p": p, "q": q}

    # 7.使用私钥 d 对明文 m 进行加密-----私钥加密(注意 m 需小于 n )
    # m = random.randint(1, n-1)
    print(f"明文:{m}")
    em = (m ** d) % n  # 加密
    print(f"私钥d加密:{em}")

    # 8.使用公钥 e 对密文 em 进行解密-----公钥解密
    dm = (em ** e) % n  # 解密
    print(f"公钥e解密:{dm}")
    if m != dm:
        print("数据对比错误,(PublicKey(n, e), PrivateKey(n, e, d, p, q))")
        return {"m": m, "em": em, "dm": dm, "n": n, "e": e, "d": d, "p": p, "q": q}


if __name__ == '__main__':
    # print(int("002".encode(), 16))
    import rsa
    (pub_key, priv_key) = rsa.key.newkeys(1024)  # 生成密钥 (PublicKey(n, e), PrivateKey(n, e, d, p, q))
    print(f"RSA公钥n:{pub_key.n},公钥e:{pub_key.e}, 模长{rsa.common.byte_size(pub_key.n)}")
    print(f"RSA私钥n:{priv_key.n},私钥e:{priv_key.e},私钥d:{priv_key.d},私钥p:{priv_key.p},私钥q:{priv_key.q}, 模长{rsa.common.byte_size(pub_key.n)}")
    data = RSA_Verification_testing()
    print("{:0256X}".format(priv_key.e), "{:0256X}".format(priv_key.d), "{:0256X}".format(priv_key.n))
    # print(f"模长{rsa.common.byte_size(data['n'])}")

    exit(0)
    for i in range(1000):
        data = RSA_Verification_testing()
        if data:
            print(f"-------第{i}次出错了,{data}-------")
            print(
                f"'e':{isprime(data['e'])}, 'd':{isprime(data['d'])},'p':{isprime(data['p'])},'q':{isprime(data['q'])}")
            break

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值