python实现RSA算法

目录

  • 一、算法简介
  • 二、算法描述
    • 2.1 密钥产生
    • 2.2 加密过程
    • 2.3 解密过程
    • 2.4 证明解密正确性
  • 三、相关算法
    • 3.1 欧几里得算法
    • 3.2 扩展欧几里得算法
    • 3.3 模重复平方算法
    • 3.4 Miller-Rabin 素性检测算法
  • 四、算法实现
  • 五、演示效果

一、算法简介

RSA算法是一种非对称加密算法,它基于一个简单的数论事实:将两个大质数相乘是容易的,但反过来,对它们的乘积进行因数分解却极其困难。RSA算法由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)在1977年共同发明,因此以他们姓氏的首字母命名。

RSA算法的特点总结,以下是一些关键点:

  1. 非对称加密

    • RSA是一种非对称加密算法,使用一对密钥:公钥用于加密,私钥用于解密。这种设计使得RSA非常适合于安全通信,因为公钥可以公开分享,而私钥必须保密。
  2. 安全性

    • RSA的安全性基于大整数分解的困难性。只要密钥长度足够长,目前没有已知的算法能在合理时间内破解RSA加密。
  3. 数字签名

    • RSA算法不仅可以用于加密,还可以用于数字签名。发送者可以用自己的私钥对消息进行签名,接收者可以用发送者的公钥验证签名,确保消息的完整性和来源。
  4. 密钥长度

    • RSA需要较长的密钥长度来保证安全性。随着计算能力的提升,推荐的密钥长度也在不断增加,目前推荐至少使用2048位的密钥长度。
  5. 计算效率

    • 相比于对称加密算法,RSA在加密和解密时的计算效率较低,特别是对于大量数据的处理。因此,RSA通常不用于大量数据的直接加密,而是用于加密对称密钥或进行数字签名。
  6. 广泛的应用

    • RSA算法被广泛应用于互联网安全通信,如SSL/TLS协议中,用于安全地传输敏感信息,如信用卡信息、个人身份信息等。
  7. 标准化

    • RSA算法已经被多个国际标准组织采纳为标准,如ISO/IEC和ITU-T。
  8. 密钥管理

    • 由于RSA使用非对称密钥,密钥管理相对复杂,需要确保私钥的安全存储和传输。
  9. 抗量子计算

    • 随着量子计算的发展,RSA算法可能面临安全威胁。量子计算机理论上能够快速分解大整数,从而破解RSA加密。因此,后量子密码学正在研究能够抵抗量子攻击的加密算法。
  10. 灵活性

    • RSA算法允许用户根据需要选择不同的参数,如密钥长度和加密指数,以满足不同的安全和性能需求。

RSA算法的这些特点使其成为现代密码学中一个非常重要的工具,尽管它也有一些局限性,如计算效率和密钥管理的复杂性。

二、算法描述

2.1 密钥产生

(1)选取两个保密大素数 p p p q q q
(2)计算模数 n = p ∗ q n=p*q n=pq n n n的欧拉函数值 φ ( n ) = ( p − 1 ) ( q − 1 ) φ(n)=(p-1)(q-1) φ(n)=(p1)(q1)
(3)在 ( 1 , φ ( n ) ) (1,φ(n)) (1,φ(n))之间任选一整数 e e e,使其满足 g c d ( e , φ ( n ) ) = 1 gcd(e,φ(n))=1 gcd(e,φ(n))=1,即 e e e φ ( n ) φ(n) φ(n)互素
(4)计算 e e e在模 φ ( n ) φ(n) φ(n)下的乘法逆元 d d d,即 e ∗ d ≡ 1 ( m o d φ ( n ) ) e*d\equiv 1\pmod{φ(n)} ed1(modφ(n)),因为 e e e φ ( n ) φ(n) φ(n)互素,由裴蜀定理可知整数 d d d一定且唯一存在
(5) { e , n } \{e,n\} {e,n}作为公钥, { d , n } \{d,n\} {d,n}作为私钥

2.2 加密过程

为了保证加解密的正确性,首先将明文 m m m进行分组,每个分组对应的十进制数值应小于模数 n n n,即分组长度小于 log ⁡ 2 n \log_2 n log2n,然后进行分组加密。 加密运算: m e m o d    n = c 加密运算:m^{e}\mod{n}=c 加密运算:memodn=c

2.3 解密过程

对密文 c c c进行分组解密 解密运算: c d m o d    n = m 解密运算:c^{d}\mod{n}=m 解密运算:cdmodn=m

2.4 证明解密正确性

由加密过程 m e m o d    n = c m^{e}\mod{n}=c memodn=c和解密过程 c d m o d    n = m c^{d}\mod{n}=m cdmodn=m,可知 c d m o d    n = m e d m o d    n c^{d}\mod{n}=m^{ed}\mod{n} cdmodn=medmodn
又因为 e ∗ d ≡ 1 ( m o d φ ( n ) ) e*d\equiv 1\pmod{φ(n)} ed1(modφ(n)),可得 e ∗ d = k φ ( n ) + 1 e*d=kφ(n)+1 ed=kφ(n)+1 k ∈ Z k\in\mathbb{Z} kZ,所以 c d m o d    n = m e d m o d    n = m k φ ( n ) + 1 m o d    n c^{d}\mod{n}=m^{ed}\mod{n}= m^{kφ(n)+1}\mod{n} cdmodn=medmodn=mkφ(n)+1modn
所以要证 c d m o d    n = m c^{d}\mod{n}=m cdmodn=m成立,即证 m k φ ( n ) + 1 m o d    n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立,注意: m < n m<n m<n
分两种情况讨论:


(1) m m m n n n互素
由欧拉定理可得, m φ ( n ) ≡ 1 ( m o d n ) m^{φ(n)}\equiv 1\pmod{n} mφ(n)1(modn),则有 m k φ ( n ) m o d    n = 1 k m o d    n = 1 m o d    n m^{kφ(n)}\mod{n}=1^k\mod{n}=1\mod{n} mkφ(n)modn=1kmodn=1modn,所以 m k φ ( n ) + 1 ≡ m ( m o d n ) m^{kφ(n)+1}\equiv m\pmod{n} mkφ(n)+1m(modn),即证 m k φ ( n ) + 1 m o d    n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立


(2) m m m n n n不互素
因为 m < n m<n m<n,所以 m m m一定为 p p p q q q的倍数,(如果 m m m同时是 p p p q q q的倍数,则 m m m一定是 p ∗ q p*q pq的倍数,与条件 m < n = p ∗ q m<n=p*q m<n=pq矛盾)。假设 m = t ∗ p m=t*p m=tp t ∈ Z + t\in\mathbb{Z}^+ tZ+,则有 g c d ( m , q ) = 1 gcd(m,q)=1 gcd(m,q)=1,由欧拉定理可得, m φ ( q ) ≡ 1 ( m o d q ) m^{φ(q)}\equiv 1\pmod{q} mφ(q)1(modq),则有 m k φ ( q ) ≡ 1 ( m o d q ) m^{kφ(q)}\equiv 1\pmod{q} mkφ(q)1(modq) m k φ ( q ) ∗ φ ( p ) = m k φ ( n ) ≡ 1 ( m o d q ) m^{kφ(q)*φ(p)}=m^{kφ(n)}\equiv 1\pmod{q} mkφ(q)φ(p)=mkφ(n)1(modq)
所以存在 r ∈ Z r\in\mathbb{Z} rZ,使得 m k φ ( n ) = r ∗ q + 1 m^{kφ(n)}=r*q+1 mkφ(n)=rq+1,等式两边同乘 m m m,可得 m k φ ( n ) + 1 = m ∗ r ∗ q + m = ( t ∗ p ) ∗ r ∗ q + m = t ∗ r ∗ n + m m^{kφ(n)+1}=m*r*q+m=(t*p)*r*q+m=t*r*n+m mkφ(n)+1=mrq+m=(tp)rq+m=trn+m
由上述等式,可得 m k φ ( n ) + 1 ≡ m ( m o d n ) m^{kφ(n)+1}\equiv m\pmod{n} mkφ(n)+1m(modn),即证 m k φ ( n ) + 1 m o d    n = m m^{kφ(n)+1}\mod{n}=m mkφ(n)+1modn=m成立
证毕!


三、相关算法

3.1 欧几里得算法

欧几里得算法,又称辗转相除法,是一种用于计算两个非负整数最大公约数(GCD)的古老算法。该算法最早由古希腊数学家欧几里得在其著作《几何原本》中描述,因此得名。

欧几里得算法的基本原理是通过不断用较大的数除以较小的数,并取余数,然后用较小的数和余数继续进行同样的操作,直到余数为0为止。此时,最后的非零余数即为这两个数的最大公约数。

其计算公式可以表示为 g c d ( a , b ) = g c d ( b , a m o d    b ) gcd(a,b)=gcd(b,a\mod{b}) gcd(a,b)=gcd(b,amodb),其中 a a a b b b是两个非负整数。
在这里插入图片描述
算法的正确性可以通过数学证明来验证。

例如,假设 x x x a a a b b b的最大公约数,则 x x x能够整除 a a a b b b,表示为 a = k 1 x , k 1 ∈ Z a=k_{1}x,k_{1}\in\mathbb{Z} a=k1x,k1Z b = k 2 x , k 2 ∈ Z b=k_{2}x,k_{2}\in\mathbb{Z} b=k2x,k2Z
由于 a m o d    b a\mod{b} amodb的结果是 a a a除以 b b b的余数,根据 a a a b b b的表达式,有 a m o d    b = ( k 1 x ) m o d    ( k 2 x ) = x ( k 1 m o d    k 2 ) a\mod{b}=(k_{1}x)\mod{(k_{2}x)}=x(k_{1}\mod{k_{2}}) amodb=(k1x)mod(k2x)=x(k1modk2),设 m = k 1 m o d    k 2 m=k_{1}\mod{k_{2}} m=k1modk2,则有 a m o d    b = x m a\mod{b}=xm amodb=xm,所以 x x x也能够整除a a m o d    b a\mod{b} amodb,因此 x x x也是 b b b a m o d    b a\mod{b} amodb的最大公约数,这说明 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a, b) = gcd(b, a mod b) gcd(a,b)=gcd(b,amodb)成立。

代码实现:递归方式

def gcd(a: int, b: int) -> int:
    """
    欧几里得算法-求两个数的最大公约数(递归版本)

    :param a: 整数
    :param b: 整数
    :return: 返回a、b的最大公约数
    """
    if b == 0:
        return a
    else:
        return gcd(b, a % b)

代码实现:非递归方式

def gcd(a: int, b: int) -> int:
    """
    欧几里得算法-求两个数的最大公约数(非递归版本)

    :param a: 整数
    :param b: 整数
    :return: 返回a、b的最大公约数
    """
    while b != 0:
        a, b = b, a % b
    return a

3.2 扩展欧几里得算法

扩展欧几里得算法(Extended Euclidean Algorithm)是欧几里得算法(也称为辗转相除法)的扩展,用于计算两个整数的最大公约数(GCD)以及找到满足裴蜀等式的整数解。具体来说,对于任意两个整数 a a a b b b,该算法不仅能计算出它们的最大公约数 d d d,还能找到整数 x x x y y y,使得 a x + b y = d ax+by=d ax+by=d成立。

扩展欧几里得算法基于裴蜀定理:对于任意两个不全为0的整数 a a a b b b,必存在整数 x x x y y y,使得 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)成立,其中 g c d ( a , b ) gcd(a,b) gcd(a,b)表示 a a a b b b的最大公约数。

推论: 如果 a a a b b b是不全为0的整数且 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1,则当且仅当存在整数 x x x y y y,使 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)成立

算法通过递归的方式,使用辗转相除法逐步缩小问题规模,直到找到最大公约数,并同时计算出对应的 x x x y y y

应用场景

  1. 求解线性不定方程:扩展欧几里得算法可以用来求解形如 a x + b y = c ax+by=c ax+by=c的线性不定方程,其中 a a a b b b c c c是已知整数, x x x y y y是未知整数。
  2. 求模逆元:在模运算中,扩展欧几里得算法可以用来求解乘法逆元,即找到一个整数 x x x使 a x ≡ 1 ( m o d n ) ax\equiv 1\pmod{n} ax1(modn),其中 n n n是模数。
  3. 求解线性同余方程:扩展欧几里得算法还可以用于求解线性同余方程,即形如 a x ≡ b ( m o d n ) ax\equiv b\pmod{n} axb(modn)的方程。

代码实现:递归方式

def ext_gcd(a: int, b: int) -> tuple:
    """
    扩展欧几里得算法-求乘法逆元(递归版本)

    :param a: 整数
    :param b: 整数
    :return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd
    """
    if b == 0:
        return (a, 1, 0)
    else:
        gcd, x1, y1 = ext_gcd(b, a % b)
        x = y1
        y = x1 - (a // b) * y1
        return (gcd, x, y)

代码实现:非递归方式

def ext_gcd(a: int, b: int) -> tuple:
    """
    扩展欧几里得算法-求乘法逆元(非递归版本)

    :param a: 整数
    :param b: 整数
    :return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd
    """
    x0, x1, y0, y1 = 1, 0, 0, 1
    while b != 0:
        q, a, b = a // b, b, a % b
        x0, x1 = x1, x0 - q * x1
        y0, y1 = y1, y0 - q * y1
    gcd, x, y = a, x0, y0
    return gcd, x, y

3.3 模重复平方算法

模重复平方算法(Modular Exponentiation by Repeated Squaring)是一种用于高效计算模幂的算法,特别适用于处理大整数幂运算。该算法的核心思想是通过将指数二进制分解,然后利用平方和乘法来计算幂的值。

该算法的优势在于其时间复杂度为 O ( log ⁡ b ) O(\log{b}) O(logb) ,显著提高了大整数幂运算的效率。因此,它在密码学中有着广泛的应用,尤其是在RSA加密算法中,用于快速计算大整数的模幂。

具体来说,模重复平方算法的基本步骤如下:计算 a b m o d    n a^{b}\mod{n} abmodn

  1. 指数二进制分解:首先将指数 b b b转换成二进制表示。例如,如果 b = 560 b=560 b=560,其二进制表示为 1000110000 1000110000 1000110000
  2. 初始化结果:初始化结果变量 d d d为1,底数变量 a a a为给定的底数
  3. 循环计算:从高位到低位遍历指数的二进制表示。首先对当前结果变量 d d d进行平方运算对模数 n n n取余;如果 b i = 1 b_{i}=1 bi=1,则再将当前结果变量 d d d乘以底数a 并对模数 n n n取余;
  4. 最终结果:当所有位都处理完毕后,得到的结果即为 a b m o d    n a^{b}\mod{n} abmodn

例如: 7 560 m o d    561 7^{560}\mod{561} 7560mod561

i i i9876543210
b i b_{i} bi1000110000
c c c01248173570140280560
d d d1749157526160241298166671

代码实现:

def quick_mod(a: int, b: int, mod: int) -> int:
    """
    模重复平方算法-大数的模幂运算

    :param a: 底数
    :param b: 指数
    :param mod: 模数
    :return: 返回余数d
    """
    c, d = 0, 1
    # 将 b 转为二进制字符串
    bin_b = bin(b)[2:]
    for i in bin_b:
        c = c * 2
        d = d * d % mod
        if i == '1':
            c = c + 1
            d = (d * a) % mod
    return d

3.4 Miller-Rabin 素性检测算法

Miller-Rabin素性检测算法是一种用于判断一个数是否为素数的概率性算法。该算法基于费马小定理的逆定理,并通过随机化方法来提高素性检测的准确性。Miler-Rabin算法的核心思想是利用费马小定理及其扩展形式。

算法检测过程
给定奇数 n ≥ 3 n\geq{3} n3和安全参数/检测次数 k k k,记 n − 1 = 2 s d n-1=2^{s}d n1=2sd d d d为奇数

  1. 随机选取整数 a a a 2 ≤ a ≤ n − 2 2\leq{a}\leq{n-2} 2an2,计算 x 0 ≡ a d ( m o d n ) x_{0}\equiv a^{d}\pmod{n} x0ad(modn)
  2. 如果 x 0 = 1 x_{0}=1 x0=1 x 0 = n − 1 x_{0}=n-1 x0=n1,则通过检验, n n n可能为素数,回到 1 1 1;否则,计算 x 1 ≡ x 0 2 ( m o d n ) x_{1}\equiv x_{0}^{2}\pmod{n} x1x02(modn)
  3. 如果 x 1 = n − 1 x_{1}=n-1 x1=n1,则通过检验,可能为素数,回到1;否则,计算 x 2 ≡ x 1 2 ( m o d n ) x_{2}\equiv x_{1}^{2}\pmod{n} x2x12(modn)
  4. 如此继续计算 x i x_{i} xi下去,直到计算到 x s − 1 x_{s-1} xs1;如果 x s − 1 = n − 1 x_{s-1}=n-1 xs1=n1,则通过检验,可能为素数,回到1;否则, n n n为合数
  5. 上述过程重复 k k k

代码实现:

def miller_rabin(n: int, k: int = 100) -> bool:
    """
    使用 Miller-Rabin 算法判断一个整数是否为素数

    :param n: 待检测的整数
    :param k: 迭代次数,k 越大,准确率越高
    :return: 如果 n 是素数,返回 True;否则返回 False
    """
    # 特殊情况处理
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0:
        return False

    # 将 n-1 写成 2^r * d 的形式
    r, d = 0, n - 1
    while d % 2 == 0:
        r += 1
        d //= 2

    # 进行 k 次迭代
    for _ in range(k):
        a = random.randint(2, n - 2)
        x = pow(a, d, n)

        if x == 1 or x == n - 1:
            continue

        for _ in range(r - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                break
        else:
            return False

    return True

四、算法实现

import random


def int2bytes(integer: int) -> bytes:
    """
    整数转换成字节串

    :param integer:
    :return: 返回字节串
    """
    # 1.计算所需的最小字节数
    if integer == 0:
        len = 1
    else:
        len = int((integer.bit_length() + 7) // 8)

    # 2.整数转换为字节串
    byte_string = integer.to_bytes(len, byteorder='big')
    return byte_string


def calculate_block_size(n: int) -> int:
    """
    计算块大小

    :param n: 模数n
    :return: 返回块大小,单位:字节/块
    """
    return (n.bit_length() - 1) // 8


def gcd(a: int, b: int) -> int:
    """
    欧几里得算法-求两个数的最大公约数

    :param a: 整数
    :param b: 整数
    :return: 返回a、b的最大公约数
    """
    while b != 0:
        a, b = b, a % b
    return a


def ext_gcd(a: int, b: int) -> tuple:
    """
    扩展欧几里得算法-求乘法逆元

    :param a: 整数
    :param b: 整数
    :return: (gcd, x, y),其中gcd是a和b的最大公约数,x和y是整数,满足 a*x + b*y = gcd
    """
    x0, x1, y0, y1 = 1, 0, 0, 1
    while b != 0:
        q, a, b = a // b, b, a % b
        x0, x1 = x1, x0 - q * x1
        y0, y1 = y1, y0 - q * y1
    gcd, x, y = a, x0, y0
    return gcd, x, y


def miller_rabin(n: int, k: int = 100) -> bool:
    """
    使用 Miller-Rabin 算法判断一个整数是否为素数

    :param n: 待检测的整数
    :param k: 迭代次数,k 越大,准确率越高
    :return: 如果 n 是素数,返回 True;否则返回 False
    """
    # 特殊情况处理
    if n <= 1:
        return False
    if n <= 3:
        return True
    if n % 2 == 0:
        return False

    # 将 n-1 写成 2^r * d 的形式
    r, d = 0, n - 1
    while d % 2 == 0:
        r += 1
        d //= 2

    # 进行 k 次迭代
    for _ in range(k):
        a = random.randint(2, n - 2)
        x = pow(a, d, n)

        if x == 1 or x == n - 1:
            continue

        for _ in range(r - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                break
        else:
            return False

    return True


def gen_prime(bits: int) -> int:
    """
    随机生成指定位数的素数

    :param bits: 指定随机生成素数的位数
    :return: 返回指定位数的随机生成素数
    """
    while True:
        # 1.生成一个随机的bits的位奇数
        candidate = random.getrandbits(bits)
        candidate |= (1 << (bits - 1)) | 1  # 确保最高位和最低位为1
        # 2.使用Miller-Rabin素性检测算法判断是否为素数
        if miller_rabin(candidate):
            return candidate


def quick_mod(a: int, b: int, mod: int) -> int:
    """
    模重复平方算法-大数的模幂运算

    :param a: 底数
    :param b: 指数
    :param mod: 模数
    :return: 返回余数d
    """
    c, d = 0, 1
    # 将 b 转为二进制字符串
    bin_b = bin(b)[2:]
    for i in bin_b:
        c = c * 2
        d = d * d % mod
        if i == '1':
            c = c + 1
            d = (d * a) % mod
    return d


def gen_key(bits: int = 1024) -> tuple:
    """
    生成密钥对

    :param bits: 指定生成p,q两个质因数的位数
    :return: (e,n),(d,n)
    """
    # 1.生成p和q两个质因数
    p = gen_prime(bits)
    while True:
        q = gen_prime(bits)
        if p != q:
            break

    # 2.计算除数n和n的欧拉函数值phi
    n = p * q
    phi = (p - 1) * (q - 1)

    # 3.生成与phi互质的公钥e
    # e=65537
    while True:
        e = random.randint(2, phi - 1)
        # 判断是e、phi否互质
        if gcd(e, phi) == 1:
            break

    # 4.计算私钥d
    # 确保d是正数并且在 phi 的范围内
    d = ext_gcd(e, phi)[1] % phi

    return (e, n), (d, n)


def rsa_encrypt(m: bytes, public_key: int, n: int) -> tuple:
    """
    RSA加密函数

    :param m: 明文
    :param public_key: 公钥
    :param n: 模数
    :return: 返回加密明文
    """
    # 1.计算块的大小
    # 保证每明文块的十进制数小于n,单位:字节/块
    block_size = calculate_block_size(n)

    # 2.进行加密
    bytes_encrypted_blocks = []
    int_encrypted_blocks = []
    for i in range(0, len(m), block_size):
        # 取出单个明文快
        block = m[i:i + block_size]
        # 将明文块转换为整数
        int_block = int.from_bytes(block, byteorder='big')
        # 对明文快进行加密
        int_encrypted_block = quick_mod(int_block, public_key, n)
        int_encrypted_blocks.append(int_encrypted_block)
        # 整数转成字节串
        bytes_encrypted_block = int2bytes(int_encrypted_block)
        bytes_encrypted_blocks.append(bytes_encrypted_block)
    return bytes_encrypted_blocks, int_encrypted_blocks  # 字节串列表/整数列表


def rsa_decrypt(c: list, private_key: int, n: int) -> tuple:
    """
    RSA解密函数

    :param c: 密文
    :param public_key: 私钥
    :param n: 模数
    :return: 返回解密密文
    """
    # 1.计算块的大小
    block_size = calculate_block_size(n)

    # 2.进行解密
    bytes_decrypted_blocks = []
    int_decrypted_blocks = []
    for block in c:
        # 将密文块转换为整数
        int_block = int.from_bytes(block, byteorder='big')
        # 对密文块进行解密
        int_decrypted_block = quick_mod(int_block, private_key, n)
        int_decrypted_blocks.append(int_decrypted_block)
        # 整数转成字节串
        bytes_decrypted_block = int2bytes(int_decrypted_block)
        bytes_decrypted_blocks.append(bytes_decrypted_block)
    return bytes_decrypted_blocks, int_decrypted_blocks  # 字节串列表/整数列表


if __name__ == '__main__':
    # 1.生成密钥对
    public_key, private_key = gen_key()
    print(f'公钥e:{public_key[0]}')
    print(f'私钥d:{private_key[0]}')
    print(f'模数n:{private_key[1]}')

    # 2.加密
    m = '你好,世界!Hello world!'
    m_ = m.encode()
    print(f'待加密明文:{m}')
    print(f'待加密明文-字节:{m_}')
    print(f'待加密明文-数字:{int.from_bytes(m_, byteorder='big')}')

    c = rsa_encrypt(m_, public_key[0], public_key[1])
    print(f'加密明文-字节:{b''.join(c[0])}')
    print(f'加密明文-数字:{c[1]}')

    # 3.解密
    m = rsa_decrypt(c[0], private_key[0], private_key[1])
    print(f'解密密文:{b''.join(m[0]).decode()}')
    print(f'解密密文-字节:{b''.join(m[0])}')
    print(f'解密密文-数字:{m[1]}')

五、演示效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/910405.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android笔记(三十一):Deeplink失效问题

背景 通过deeplink启动应用之后&#xff0c;没关闭应用的情况下&#xff0c;再次使用deeplink会失效的问题&#xff0c;是系统bug导致的。此bug仅在某些设备&#xff08;Nexus 5X&#xff09;上重现&#xff0c;launchMode并且仅当应用程序最初通过深层链接启动并再次通过深层…

基于Multisim拔河比赛游戏+计分电路(含仿真和报告)

【全套资料.zip】拔河比赛游戏计分电路Multisim仿真设计数字电子技术 文章目录 功能一、Multisim仿真源文件二、原理文档报告资料下载【Multisim仿真报告讲解视频.zip】 功能 1.拔河游戏机用9个发光二极管排成一行。 2.开机后只有中间一个点亮&#xff0c;以此作为拔河的中心…

A20红色革命文物征集管理系统

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

面向 TP 场景能力全面升级, OceanBase 4.2.5 LTS 版正式发布

去年的 OceanBase 年度发布会中&#xff0c;OceanBase 推出了一体化数据库的首个长期支持版——4.2.1 LTS。这一年来&#xff0c;已有数百位客户在真实的生产环境中对该版本进行了验证并成功上线&#xff0c;证明了OceanBase 在TP场景中的卓越性能。与此同时&#xff0c;越来越…

在线预览 Word 文档

引言 随着互联网技术的发展&#xff0c;Web 应用越来越复杂&#xff0c;用户对在线办公的需求也日益增加。在许多业务场景中&#xff0c;能够直接在浏览器中预览 Word 文档是一个非常实用的功能。这不仅可以提高用户体验&#xff0c;还能减少用户操作步骤&#xff0c;提升效率…

MongoDB笔记02-MongoDB基本常用命令

文章目录 一、前言二、数据库操作2.1 选择和创建数据库2.2 数据库的删除 3 集合操作3.1 集合的显式创建3.2 集合的隐式创建3.3 集合的删除 四、文档基本CRUD4.1 文档的插入4.1.1 单个文档插入4.1.2 批量插入 4.2 文档的基本查询4.2.1 查询所有4.2.2 投影查询&#xff08;Projec…

对称二叉树(力扣101)

题目如下: 思路 对于这道题, 我会采用递归的解法. 看着对称的二叉树, 写下判断对称的条件, 再进入递归即可. 值得注意的是, 代码中会有两个函数, 第一个是isSymmetric,第二个是judge. 因为这里会考虑到一种特殊情况, 那就是 二叉树的根结点(最上面的那个),它会单独用…

基于SSM的社区物业管理系统+LW参考示例

1.项目介绍 系统角色&#xff1a;管理员、业主&#xff08;普通用户&#xff09;功能模块&#xff1a;管理员&#xff08;用户管理、二手置换管理、报修管理、缴费管理、公告管理&#xff09;、普通用户&#xff08;登录注册、二手置换、生活缴费、信息采集、报事报修&#xf…

【pycharm jupyter】远程开发 启动报错

报错信息 upyter server process exited with code 1 ServerApp] A _jupyter_server_extension_points function was not found in jupyter_lsp. Instead, a _jupyter_server_extension_paths function was found and will be used for now. This function name will be depre…

软件设计师-上午题-12、13 软件工程(11分)

软件工程题号一般为17-19和29-36题&#xff0c;分值一般为11分。 目录 1 软件过程 1.1 CMM(能力成熟度模型) 1.1.1 真题 1.2 CMMI(能力成熟度模型集成) 1.2.1 真题 2 软件过程模型 2.1 瀑布模型 2.2 V模型 2.2.1 真题 2.3 增量模型 2.3.1 真题 2.4 演化模型 2.5 …

基于springboot得高校评教教师工作量管理系统设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

vue3 ref对象的width改变了,并不会直接去更新视图,但是触发obj.width++是可以正常更新视图的简单处理方法

1、服务器返回的是一个对象Obj&#xff0c;结构如下&#xff1a; {id: 999,width: 100,height:500, } 2、定义一个变量const objRef ref(); 3、视图&#xff1a; 4、这样是可以触发更新的&#xff1a; 说明&#xff1a;直接去更新这个width值&#xff0c;会自动触发这个div…

“立桩升量”,大智慧+通达信精品公式,上涨途中抓大趋势 源码无限制

使用技巧 立桩升量是指一只股票在上升途中&#xff0c;在相对低位放出一根阶段性的大量&#xff08;超越和覆盖掉前期的量&#xff09;&#xff0c;成交量呈现阶段性放大趋势&#xff0c;同时股票价格处于上涨趋势&#xff0c;以上两点缺一不可。特别强调的是&#xff0c;立桩…

Linux系统的文件系统和日志和管理

文件系统 stat命令 查看文件系统可用的inode号 平时涉及到的环境 inode号和文件名分离&#xff0c;使得linux会出现一下几个现象 模拟inode号耗尽的情况 分别创建ext4文件系统的sdb2和xfs文件系统的sdb3 ext4 因为inode号用完而导致无法创建文件 硬盘还有空间&#xff0c;但i…

SQL Server身份验证模式

SQL Server是一个广泛使用的关系数据库管理系统&#xff0c;通常使用两种身份验证模式&#xff1a;Windows身份验证和SQL Server身份验证。理解这些身份验证方式的概念与更改方式的操作&#xff0c;对于数据库管理员和开发者至关重要。本文将详细介绍身份验证方式的概念以及如何…

SpringBoot+FileBeat+ELK8.x版本收集日志

一、准备环境 1、ElasticSearch&#xff1a;8.1.0 2、FileBeat&#xff1a;8.1.0 3、Kibana&#xff1a;8.1.0 4、logstach&#xff1a;8.1.0 本次统一版本&#xff1a;8.1.0,4个组件&#xff0c;划分目录&#xff0c;保持版本一致。 说明&#xff1a;elasticsearch和kib…

tiktok付费广告效果说明经验分享

付费ROAS&#xff08;站内&#xff09; 付费ROAS&#xff08;Return On Advertising Spend&#xff09;是指归因于广告的付费事件所产生的总广告支出回报率。这是衡量广告效果的关键指标之一&#xff0c;能够反映广告投入与收益之间的比例关系。 计算公式&#xff1a; ROAS(流…

vue中实现列表无缝动态滚动

要想实现列表的动态无缝滚动&#xff0c;这里推荐两款组件&#xff0c;vue-seamless-scroll和vue3-seamless-scroll&#xff0c;组件的用法也非常简单&#xff0c;以下是使用方式。 vue2 vue2版本使用vue-seamless-scroll vue-seamless-scroll文档https://chenxuan0000.gith…

A Consistent Dual-MRC Framework for Emotion-cause Pair Extraction——论文阅读笔记

前言 这是我第一次向同学院同年级的学生和老师们汇报的第一篇论文,于2022年发表在TOIS上,属于CCF A类,主要内容是将MRC应用到情感原因对抽取中。 论文链接:用于情绪-原因对提取的一致双 MRC 框架 |信息系统上的 ACM Transactions 这里我就不放上我自己翻译的中文版还有我…

【docker】5. 背景知识(了解)

Docker 是什么 Docker 本质 Docker 本质其实是 LXC 之类的增强版&#xff0c;它本身不是容器&#xff0c;而是容器的易用工具。容器是 linux 内核中的技术&#xff0c;Docker 只是把这种技术在使用上简易普及了。Docker 在早期的版本其核心就是 LXC 的二次封装发行版。 Docke…