如何使用 Python 解密使用 PEM RSA 私钥加密的 Windows EC2 实例密码?

How to decrypt Windows EC2 instance password that was encrypted with a PEM RSA private key using Python?

我想 Python 使用 PEM RSA 密钥解密文本。具体来说,我要解密的文本是get_password_data() boto3 function.

返回的加密密码数据

我查看了 ,但它对我不起作用。

我正在使用 pycryptodome,我已经安装了

python3 -m pip install --user pycryptodome

我的密钥文件是 PEM RSA 私钥:

$ file my_key.pem
my_key.pem: PEM RSA private key

这是我的代码,它基于上面链接的答案:

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5

encrypted_password = '<redacted>'

rsa_key = RSA.importKey(open('my_key.pem', 'rb').read())
cipher = PKCS1_v1_5.new(rsa_key)
password = cipher.decrypt(encrypted_password) # This line throws the error below
print(f'{password=}')

当我运行这个时,我得到这个错误信息:

AttributeError: 'PKCS115_SigScheme' object has no attribute 'decrypt'

完整追溯:

Traceback (most recent call last):
  File "/home/shane/src/experimentation/decrypt_password_so_example.py", line 8, in <module>
    password = cipher.decrypt(encrypted_password) # This line throws the error below
AttributeError: 'PKCS115_SigScheme' object has no attribute 'decrypt'

我做错了什么?

通过深入研究 AWS CLI 源代码,我找到了基于 this function 中代码的解决方案。

我努力寻找解决方案的原因是 boto3 EC2 文档没有解释返回的 PasswordData 是 base64 编码的。

这是我的解决方案(请注意,此解决方案需要 rsa module):

import boto3
import base64
import rsa

def decrypt_password_data(password_data, pk_path):
    encrypted_password = password_data['PasswordData']

    with open(pk_path) as pk_file:
        pk_contents = pk_file.read()

    private_key = rsa.PrivateKey.load_pkcs1(pk_contents.encode('latin-1'))
    value = base64.b64decode(encrypted_password)
    value = rsa.decrypt(value, private_key)
    decrypted_password = value.decode('utf-8')

    return decrypted_password

用法,如果你有 EC2.Instance object (password_data() docs):

password_data = instance.password_data(DryRun=False)
password = decrypt_password_data(password_data, '/path/to/key')

用法,如果你有 EC2.Client object (get_password_data() docs):

password_data = ec2_client.get_password_data(
    InstanceId='i-1234567',  # Replace as needed
    DryRun=False
)
password = decrypt_password_data(password_data, '/path/to/key')

如果您不需要在 Python 中执行此操作并且您有 AWS CLI installed, you can instead to this (get-password-data docs link;请注意,这会输出一个 JSON 对象):

aws ec2 get-password-data --instance-id <instance_id> --priv-launch-key /path/to/key

请注意 boto3 文档中的以下内容:

When you launch an instance, password generation and encryption may take a few minutes. If you try to retrieve the password before it's available, the output returns an empty string.