python模块 — rsa

1、rsa模块介绍

rsa模块是一个纯Python实现的第三方库,用于密码学中的加密和解密数据。该模块提供了函数和类来生成RSA密钥对、进行加密和解密操作,以及进行数字签名和验证等操作。

官网地址:rsa · PyPI

版本要求:Python >=3.6, <4

安装:pip install rsa

文档:Welcome to Python-RSA’s documentation! — Python-RSA 4.8 documentation

2、生成秘钥

rsa模块中使用`rsa.newkeys()`函数生成RSA密钥对,这个函数会返回一个包含公钥和私钥的元组。

语法格式如下:

newkeys(
    nbits: int,
    accurate: bool = True,
    poolsize: int = 1,
    exponent: int = DEFAULT_EXPONENT,
) -> typing.Tuple[PublicKey, PrivateKey]

参数说明:

  •  `nbits`:生成的密钥长度(以位为单位)。为了安全性考虑,一般建议选择1024位以上的长度。常见的长度包括2048位和4096位等。
  • `accurate`:是否在生成密钥时进行精确的素数检查。默认为True,表示进行精确检查,可以确保生成的密钥是素数。如果设置为False,生成速度可能会更快,但密钥的素数性质会稍微减弱。
  • `poolsize`:并行生成RSA密钥对的线程池大小。默认为1,表示单线程生成密钥对。如果设置为大于1的值,可以加快生成密钥对的速度。
  • `exponent`:密钥的指数值。默认为0x10001(65537),是RSA算法中常用的指数值。

 用法示例如下:

import rsa

# 指定密钥的位数,例如2048
key_size = 2048

# 生成RSA密钥对
public_key, private_key = rsa.newkeys(key_size)

# 打印生成的公钥和私钥
print("Public Key:", public_key)
print("Private Key:", private_key)

在上面的代码中,我们使用rsa.newkeys()函数并传入密钥的位数作为参数,例如2048。函数会返回一个元组,其中第一个元素是公钥,第二个元素是私钥。我们可以打印出生成的公钥和私钥。

请注意,密钥的位数越大,安全性就越高,但生成和处理密钥的时间也会增加。一般来说,2048位的密钥已经足够安全,如果需要更高的安全性,可以选择更大的位数。

需要注意的是,使用rsa库生成的RSA密钥对是纯Python实现的,用于学习和简单应用。如果要在实际生产环境中使用RSA加密,建议使用更强大和更安全的密码学库,比如cryptography

3、保存秘钥

在Python的`rsa`库中,可以使用 `save_pkcs1()` 方法将生成的RSA密钥保存为PEM文件。

语法格式如下:

    def save_pkcs1(self, format: str = "PEM") -> bytes:
        """Saves the key in PKCS#1 DER or PEM format."""

参数说明:

  • format:保存的格式,可选值为"PEM"或"DER"。默认为"PEM"。指定为"PEM"时,密钥将保存为可打印的PEM格式(ASCII编码)。指定为"DER"时,密钥将保存为二进制DER格式。
  • 返回值:该方法的返回值是一个字节字符串(bytes),表示保存的PKCS#1格式的RSA密钥。 

下面是一个保存RSA密钥为PEM文件的示例代码:

import rsa

# 生成RSA密钥对
(public_key, private_key) = rsa.newkeys(2048)

# 将公钥保存到PEM文件中
with open('public_key.pem', 'wb') as file:
    file.write(public_key.save_pkcs1())

# 将私钥保存到PEM文件中
with open('private_key.pem', 'wb') as file:
    file.write(private_key.save_pkcs1())

在上面的代码中,我们使用 `rsa.newkeys()` 方法生成一个2048位的RSA密钥对。然后,我们使用 `public_key.save_pkcs1()` 方法将公钥转换为PEM格式,并将其保存到名为 "public.pem" 的文件中。类似地,我们使用 `private_key.save_pkcs1()` 方法将私钥转换为PEM格式,并将其保存到名为 "private.pem" 的文件中。

保存后的PEM文件可以在其他程序中读取和使用。需要注意的是,在实际应用中,对私钥的保护要非常重要,确保只有授权的人能够访问。

4、加载秘钥

在Python的rsa库中,你可以使用`load_pkcs1()`方法从PEM文件中加载PKCS#1格式的RSA密钥。

语法格式如下:

    def load_pkcs1(cls: typing.Type[T], keyfile: bytes, format: str = "PEM") -> T:
        """Loads a key in PKCS#1 DER or PEM format."""

参数说明:

  • cls:方法的类对象,通常为rsa.key.PrivateKey。
  • keyfile:PEM文件的字节串形式,包含RSA密钥。
  • format:PEM文件的格式,默认为"PEM"。支持的格式包括"PEM"和"DER"。
  • 返回值:方法会返回一个RSA密钥对象,可以用于加密、解密、签名和验签等操作。

以下是一个使用示例:

import rsa

# 从PEM文件中加载公钥
with open('public_key.pem', 'rb') as file:
    public_key_data = file.read()
    public_key = rsa.PublicKey.load_pkcs1(public_key_data)

# 从PEM文件中加载私钥
with open('private_key.pem', 'rb') as file:
    private_key_data = file.read()
    private_key = rsa.PrivateKey.load_pkcs1(private_key_data)

在这个示例中,我们使用`load_pkcs1()`方法从PEM文件中加载私钥和公钥。首先,我们以二进制模式(`"rb"`)打开PEM文件,并将其读取为字节字符串。然后,我们将字节字符串传递给`load_pkcs1()`方法,从而加载RSA密钥。

使用`load_pkcs1()`方法加载密钥时,请确保PEM文件包含正确格式的RSA密钥。如果PEM文件的格式不正确,可能会导致加载失败。同时,务必保护好加载的私钥,确保只有授权的人能够访问。

5、加密和解密

5.1 加密

在`rsa`模块中,可以使用 `rsa.encrypt()` 函数来加密数据。

语法格式:

def encrypt(message: bytes, pub_key: key.PublicKey) -> bytes:
    """Encrypts the given message using PKCS#1 v1.5"""

参数说明:

  • message:要加密的消息,数据类型是bytes。
  • pub_key:RSA公钥对象,用于加密数据。通常是 rsa.key.PublicKey 类的实例。
  • 返回值:该方法返回加密后的数据,以字节串形式表示。

以下是一个使用 `rsa.encrypt()` 函数加密数据的示例代码:

import rsa

# 生成RSA密钥对
public_key, private_key = rsa.newkeys(2048)

# 要加密的数据
message = b"Hello, RSA!"

# 使用RSA公钥加密数据
encrypted_data = rsa.encrypt(message, public_key)

print("加密后的数据:", encrypted_data)

需要注意的是,加密后的数据是以字节串形式存储的。通常情况下,你可能需要将加密后的数据转换成可传输或存储的格式,比如Base64编码,以便后续的操作。

5.2 解密

在`rsa`模块中,可以使用 `rsa.decrypt()` 函数来解密使用RSA公钥加密的数据。

 语法格式:

def decrypt(crypto: bytes, priv_key: key.PrivateKey) -> bytes:
    r"""Decrypts the given message using PKCS#1 v1.5"""

参数说明:

  • crypto:要解密的密文消息,数据类型是bytes。
  • priv_key:RSA私钥对象,用于解密数据。通常是 rsa.key.PrivateKey 类的实例。
  • 返回值:该方法返回解密后的数据,以字节串形式表示。

以下是一个使用 `rsa.decrypt()` 函数解密数据的示例代码:

import rsa

# 生成RSA密钥对
public_key, private_key = rsa.newkeys(2048)

# 要加密的数据
message = b"Hello, RSA!"

# 使用RSA公钥加密数据
encrypted_data = rsa.encrypt(message, public_key)

# 使用RSA私钥解密数据
decrypted_data = rsa.decrypt(encrypted_data, private_key)

print("解密后的数据:", decrypted_data)

需要注意的是,解密操作需要使用与加密使用的公钥相对应的私钥。确保使用正确的私钥进行解密,以获取原始的明文数据。

6、签名和认证

6.1 签名

在`rsa`模块中,可以使用`rsa.sign`函数对数据进行签名。

语法格式:

def sign(message: bytes, priv_key: key.PrivateKey, hash_method: str) -> bytes:
    """Signs the message with the private key."""

参数说明:

  • `message`:要签名的消息,数据类型是`bytes`。
  • `priv_key`:表示RSA私钥的对象,可以是通过`rsa.PrivateKey`函数创建的私钥对象。
  • `hash_method`:可选参数,用于指定哈希算法。默认值为`'SHA-1'`,可选的哈希算法有`'MD5'`、`'SHA-1'`、`'SHA-224'`、`'SHA-256'`、`'SHA-384'`、`'SHA-512'`等。
  • 返回值:该方法返回消息的签名,以字节串形式表示。

以下是一个示例代码,演示如何使用 sign() 方法使用RSA私钥对消息进行签名:

import rsa

# 生成RSA密钥对
public_key, private_key = rsa.newkeys(2048)

# 要签名的消息
message = b"Hello, RSA!"

# 使用RSA私钥对消息进行签名
signature = rsa.sign(message, private_key, "SHA-256")

print("签名结果:", signature)

需要注意的是,签名后的结果是以字节串形式存储的。通常情况下,你可能需要将签名结果转换成可传输或存储的格式,比如Base64编码,以便后续的操作。

6.2 验签(认证)

在`rsa`模块中,可以使用`rsa.verify`函数验证签名的有效性。

语法格式:

def verify(message: bytes, signature: bytes, pub_key: key.PublicKey) -> str:
    """Verifies that the signature matches the message."""

参数说明:

  • `message`:要验证签名的消息,数据类型是`bytes`。
  • `signature`:要验证的签名,以字节串形式传递。
  • `pub_key`:RSA公钥对象,可以是通过`rsa.PublicKey`函数创建的公钥对象。
  • 返回值:该方法返回一个字符串,表示签名的验证结果。如果签名验证成功,返回字符串 "签名有效";如果签名验证失败,返回字符串 "签名无效"。

以下是一个示例代码,演示如何使用 verify() 方法验证签名的有效性:

import rsa

# 生成RSA密钥对
public_key, private_key = rsa.newkeys(2048)

# 要签名的消息
message = b"Hello, RSA!"

# 使用RSA私钥对消息进行签名
signature = rsa.sign(message, private_key, "SHA-256")

# 验证签名的有效性
verification_result = rsa.verify(message, signature, public_key)

print("签名验证结果:", verification_result)

需要注意的是,签名时所使用的哈希算法与验证签名时所使用的哈希算法必须一致。


reference:

rsa · PyPI

Welcome to Python-RSA’s documentation! — Python-RSA 4.8 documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值