在 Python 密码库中提取模数 n、私有指数和 public 指数

Extract modulus n, private exponent and public exponent in Python cryptography library

我正在使用 Python cryptography 库,我需要用 RSA 加密一些东西。一切都很好,除了一件事。

生成密钥时,我需要获取十六进制形式的模数 n、public 指数和私有指数,以便我可以将它们保存到自定义格式的文件中。这不是为了现实世界的使用,我是为了 class 作业而做的。

我搜索了整个 cryptography 有关 RSA 的文档,但找不到任何方法,例如 get_modulus_or_exponents() 或任何可能暗示类似内容的方法。

我能想到的获取这些数字的唯一方法是序列化密钥,然后 subprocess openssl 命令并以如下形式读取它:

Modulus (2048 bit):
    00:98:10:23:16:ff:b6:f4:26:a2:42:a6:19:23:0e:
    0f:27:4a:b9:43:3d:a0:4b:b9:1b:1a:57:92:dd:a8:
    bc:5d:b8:6e:e6:7f:0f:2e:89:a5:77:16:d1:cf:44:
    [...]
    f3:0d:5b:90:6b:de:59:58:c9:f4:26:4a:61:b4:52:
    21:1d
Exponent: 65537 (0x10001)

对其进行解析,并提取所需的信息。

有没有比这个变通方法更好的方法(最好使用 cryptography 的工具)(我在文档中遗漏了什么?)或者 cryptography 真的不允许任何其他方法来获取需要信息吗?

编辑:这是我用来生成密钥和加密的代码,与文档示例基本相同:

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa

private_key = rsa.generate_private_key(public_exponent=65537,
                                           key_size=self.key_size * 8,
                                           backend=default_backend()
                                           )
public_key = private_key.public_key()
ciphertext = public_key.encrypt(message, padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA1()),algorithm=hashes.SHA1(),label=None))

您可以使用 public_numbers()private_numbers()

访问
 public_key.public_numbers()
 private_key.private_numbers()

查看可用内容的一个好方法是使用 dir:

In [13]: [a for a in dir(public_key) if not a.startswith("_")]
Out[13]: ['encrypt', 'key_size', 'public_bytes', 'public_numbers', 'verifier']

In [14]: [a for a in dir(private_key) if not a.startswith("_")]
Out[14]: 
['decrypt',
 'key_size',
 'private_bytes',
 'private_numbers',
 'public_key',
 'signer']


In [15]: [a for a in dir(private_key.private_numbers()) if not a.startswith("_")]
Out[15]: ['d', 'dmp1', 'dmq1', 'iqmp', 'p', 'private_key', 'public_numbers', 'q']

In [16]: [a for a in dir(public_key.public_numbers()) if not a.startswith("_")]
Out[16]: ['e', 'n', 'public_key']

In [17]: [a for a in dir(private_key.private_numbers().public_numbers) if not a.startswith("_")]
Out[17]: ['e', 'n', 'public_key']

你看你实际上可以只使用私钥访问所有属性。