RSA加密算法的实现

 

实验过程

编写程序调用gmpy.2的大素数生成算法,生成不同的素数。

import gmpy2

# 创建随机数生成器的状态
rs = gmpy2.random_state()

# 生成大素数
def create_prime():
    p = gmpy2.mpz_urandomb(rs, 1024)  # 随机生成一个0~2^1024的数
    while not gmpy2.is_prime(p):  # 判断生成的数是否是素数
        p = gmpy2.mpz_urandomb(rs, 1024)
    return p

编写RSA程序,在程序中调用大素数生成算法生成需要的素数。

# 生成RSA公钥和私钥
def generate_keypair():
    # 调用素数生成函数生成两个素数
    p = create_prime()
    q = create_prime()
    # p=2357
    # q=2551
    n = p * q  # 计算模数
    # print(n)
    phi = (p - 1) * (q - 1)  # 计算Euler函数值

    e = gmpy2.next_prime(gmpy2.mpz(65537))  # 选择公钥e (通常选择65537)
    # print(e)
    # e=3674911
    pub_key = (n, e)
    print(f'生成的公钥为:({n},{e})')
    d = gmpy2.invert(e, phi)  # 计算私钥d
    print('生成的私钥为:', d)
    # 返回公钥和私钥
    return pub_key, d

用较小的x<1,000,000,000尝试采用传统方法计算模指数,即

5f2ba61ab00f4366852fba33d6b66752.png 的方法。

# 传统方法计算模指数
def mod_exp(base, exp, modulus):
    result = 1
    for _ in range(exp):
        result = (result * base) % modulus
    return result


base = 5234673
exp = 3674911
modulus = 6012707

result = mod_exp(base, exp, modulus)
print(f'模指数计算结果为(传统方式):{result}')

尝试用模运算的快速算法计算模指数(称为重复平方相乘法),即将指数写成二进制的形式,如果b=35,可以写成b=1000011,则

56a2513c0e67458aa64b21297ef1d35c.png

x = 5234673  # 密文
y = 3674911  # 指数
m = 6012707  # 模
result = 1
while y > 0:
    if y % 2 == 1:
        result = (result * x) % m
    x = (x * x) % m
    y = y // 2
print("Result:", result)

最后,利用快速模指数运算法实现RSA加密与解密算法。

完整代码如下:

import gmpy2

# 创建随机数生成器的状态
rs = gmpy2.random_state()


# 生成大素数
def create_prime():
    p = gmpy2.mpz_urandomb(rs, 100)  # 随机生成一个数
    while not gmpy2.is_prime(p):  # 判断生成的数是否是素数
        p = gmpy2.mpz_urandomb(rs, 100)
    return p


# 生成RSA公钥和私钥
def generate_keypair():
    # 调用素数生成函数生成两个素数
    p = create_prime()
    q = create_prime()
    print(f'生成的大素数(即p、q)为:{p}、{q}')
    # p=2357
    # q=2551
    n = p * q  # 计算模数
    # print(n)
    phi = (p - 1) * (q - 1)  # 计算Euler函数值

    e = gmpy2.next_prime(gmpy2.mpz(65537))  # 选择公钥e (通常选择65537)
    # print(e)
    # e=3674911
    pub_key = (n, e)
    print(f'生成的公钥为:({n},{e})')
    d = gmpy2.invert(e, phi)  # 计算私钥d
    print('生成的私钥为:', d)
    # 返回公钥和私钥
    return n, e, d


# 快速模指数运算
def mod_exp(base, exp, modulus):
    result = 1
    while exp > 0:
        if exp % 2 == 1:
            result = (result * base) % modulus
        base = (base * base) % modulus
        exp = exp // 2
    return result


# RSA加解密
def rsa_encrypt(message, public_key, modulus):
    return mod_exp(message, public_key, modulus)


def rsa_decrypt(ciphertext, private_key, modulus):
    return mod_exp(ciphertext, private_key, modulus)


def main():
    modulus, public_key, private_key = generate_keypair()

    plaintext = int(input("请输入要加密的明文: "))
    cipher = rsa_encrypt(plaintext, public_key, modulus)

    print(f'明文:{plaintext}')
    print(f'加密的结果为:{cipher}')

    message = rsa_decrypt(cipher, private_key, modulus)
    print(f'密文:{cipher}')
    print(f'解密的结果为:{message}')


if __name__ == "__main__":
    main()

运行结果

3fbe2bb0ac474317b901636ccebc62b3.png

要判断编写的程序是否正确,可以使用已知正确的算法求出结果进行验证,例如用gmpy2库进行运算,与自己得出的结果比较。

import gmpy2

number1 = gmpy2.mpz(930171431646201037747253461007)
number2 = gmpy2.mpz(696068596238208926722796423131)

# 使用gmpy2库计算两个大数相乘
result_gmpy2 = number1 * number2
print(f'gmpy2计算得到的结果为:{result_gmpy2}')
# 使用自己实现的代码计算两个大数相乘
result_custom = 647463122686856263479122264333657511736515464117119781352917

# 比较结果是否一致
if result_gmpy2 == result_custom:
    print('结果正确!')
else:
    print('结果错误!')

可以检验程序的正确性。

be925a171b504e5686bbecedee769104.png

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Issme

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值