教你用python写RSA加密算法

教你用python写RSA加密算法

RSA加密算法简介

RSA加密算法是一种非对称加密算法,即使用不同的密钥进行加密和解密。它是由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年提出的,是目前最广泛使用的公钥加密算法之一 。

RSA加密算法的原理是基于数论中的一个难题:大数分解。给定一个大整数n,将其分解为两个素数p和q的乘积是非常困难的,但如果已知p和q,则可以很容易地计算出n。因此,可以将n作为公开的信息,而将p和q保密作为私有的信息。这样,只有知道p和q的人才能对n进行因式分解,从而破解RSA加密算法 。

步骤

RSA加密算法的具体步骤如下:

  • 公钥和私钥的生成:
    • 随机选择两个大素数p和q,计算n = p * q。
    • 根据欧拉函数,求得r = φ(n) = (p – 1) * (q – 1)。
    • 随机选择一个小于r的整数e,使得e与r互质。
    • 求得e关于r的模逆元素d,即满足ed ≡ 1 (mod r) 的整数d。
    • 将n和e作为公钥,将d作为私钥。
  • 加密过程:
    • 将明文m(m < n)转换为一个整数m’。
    • 使用公钥(n, e)对m’进行加密,得到密文c’,计算方法为c’ = m’^e mod n。
  • 解密过程:
    • 使用私钥d对c’进行解密,得到明文m’,计算方法为m’ = c’^d mod n。
    • 将m’转换回原来的明文m。

代码

下面我们用python实现RSA加密算法,并给出一个简单的示例:

import random
import math

# 求两个数的最大公约数
def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

# 计算e在模phi意义下的乘法逆元d
def multiplicative_inverse(e, phi):
    d = 0
    x1 = 0
    x2 = 1
    y1 = 1
    temp_phi = phi

    while e > 0:
        # 辗转相除求gcd和乘法逆元
        temp1 = temp_phi // e
        temp2 = temp_phi - temp1 * e
        temp_phi = e
        e = temp2

        x = x2 - temp1 * x1
        y = d - temp1 * y1

        x2 = x1
        x1 = x
        d = y1
        y1 = y

    if temp_phi == 1:  # 如果e和phi互质,则返回d+phi
        return d + phi

# 生成RSA密钥对
def generate_keypair(p, q):
    n = p * q  # 计算n
    phi = (p-1) * (q-1)  # 计算phi

    # 选择一个随机整数e使得1 < e < phi且e与phi互质
    e = random.randrange(1, phi)
    g = gcd(e, phi)
    while g != 1:  # 如果e和phi不互质,重新选择e
        e = random.randrange(1, phi)
        g = gcd(e, phi)

    # 计算e的乘法逆元d
    d = multiplicative_inverse(e, phi)

    # 返回公钥和私钥
    return ((e, n), (d, n))

# 加密消息
def encrypt(public_key, plaintext):
    key, n = public_key
    # 对明文中的每个字符进行加密,并将结果存储在列表cipher中
    cipher = [(ord(char) ** key) % n for char in plaintext]
    return cipher

# 解密消息
def decrypt(private_key, ciphertext):
    key, n = private_key
    # 对密文中的每个数字进行解密,并将结果存储在列表plain中
    plain = [chr((char ** key) % n) for char in ciphertext]
    # 将plain列表转换为字符串并返回
    return ''.join(plain)

if __name__ == '__main__':
    # 选择两个质数p和q
    p = 17
    q = 19

    # 生成RSA密钥对
    public, private = generate_keypair(p, q)
    print("公钥: ", public)
    print("私钥: ", private)

    # 加密和解密消息
    message = "Hello world"
    encrypted_message = encrypt(public, message)
    decrypted_message = decrypt(private, encrypted_message)

    # 输出原始消息、加密后的消息和解密后的消息
    print("原始消息: ", message)
    print("加密后的消息: ", encrypted_message)
    print("解密后的消息: ", decrypted_message)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
青葱年少的头像青葱年少普通用户
上一篇 2023年6月20日
下一篇 2023年6月20日

相关推荐