将PEM文件转换为DER

时间:2016-03-14 01:39:50

标签: python cryptography tor

我目前正在尝试编写一个脚本,允许我从hiddens服务的私钥文件中计算Tor HS地址。 为了做到这一点,需要将文件带入DER格式。

使用OpenSSL可以通过以下方式完成:

openssl rsa -in private_key -pubout -outform DER

使用以下命令将其管道化为python:

base64.b32encode(hashlib.sha1(sys.stdin.read()[22:]).digest()[:10]).lower()'

将正确返回地址。

但是我想只使用python执行相同的操作。我的问题是使用pycrypto模块DER输出是不同的,因此地址不正确。

key = RSA.importKey(keyfile.read()).publickey()
print(key.exportKey(format='DER'))

将导致与openssl调用不同的输出。 这只是一个允许不同结果的实施问题吗?或者我在某处犯了错误?

任何帮助将不胜感激

4 个答案:

答案 0 :(得分:4)

使用python

将证书转换为der

首先我们加载文件

cert_file = keyfile.read()

然后我们将其转换为pem

cert_pem = crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_file)

现在我们正在生成der输出
即:输出等于openssl x509 -outform der -in certificate.pem -out certificate.der。

cert_der = crypto.dump_certificate(crypto.FILETYPE_ASN1,cert_pem)

希望有所帮助

答案 1 :(得分:1)

我一直在寻找类似的东西,从2019年3月开始,OpenSSL建议使用pyca/cryptography而不是crypto模块。 (source

那么您打算做什么:将PEM转换为DER

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization

with open("id_rsa", "rb") as keyfile:
    # Load the PEM format key
    pemkey = serialization.load_pem_private_key(
        keyfile.read(),
        None,
        default_backend()
    )
    # Serialize it to DER format
    derkey = pemkey.private_bytes(
        serialization.Encoding.DER,
        serialization.PrivateFormat.TraditionalOpenSSL,
        serialization.NoEncryption()
    )
    # And write the DER format to a file
    with open("key.der", "wb") as outfile:
        outfile.write(derkey)

答案 2 :(得分:1)

我希望将证书文件而不是将密钥文件从DER转换为PEM,但是Google将我带到了这里。感谢@ alleen1的回答,我可以将证书或密钥从DER转换为PEM,反之亦然。

第一步,加载文件。

第二步,将其保存为所需的格式。

我省略了获取“ pem_data”和“ der_data”的过程,您可以从文件或其他任何地方获取它。它们应该是字节而不是字符串,需要时使用方法.encode()。

from cryptography import x509
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend

# Step one, load the file. 

# Load key file
# PEM 
key = serialization.load_pem_private_key(pem_data, None, default_backend())
# DER
key = serialization.load_pem_private_key(der_data, None, default_backend())

# Load cert file
# PEM
cert = x509.load_pem_x509_certificate(pem_data, default_backend())
# DER
cert = x509.load_der_x509_certificate(der_data, default_backend())

# Step two,save it to the format you want.
# PEM key
key_val = key.private_bytes(
              serialization.Encoding.PEM,
              serialization.PrivateFormat.TraditionalOpenSSL,
              serialization.NoEncryption()
          )
# DER key
key_val = key.private_bytes(
              serialization.Encoding.DER,
              serialization.PrivateFormat.TraditionalOpenSSL,
              serialization.NoEncryption()
          )

# PEM cert
cert_val = cert.public_bytes(serialization.Encoding.PEM)
# DER cert
cert_val = cert.public_bytes(serialization.Encoding.DER)

答案 3 :(得分:0)

初始问题是:“ 从私钥中确定公钥”,这是因为openSSL命令在最初的问题中声明了“发布”。

使用OpenSSL可以通过以下方式完成:(请注意,“发布”将OUTPUT定义为仅公开密钥)

openssl ALGORITHM_USED -in private_key -pubout -outform DER

但是使用Python加密模块,您可以从私钥中提取公钥(请注意,这似乎适用于基于RSA和EC的加密)。

使用Python:

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.backends import default_backend

    # Create private key (example uses elliptic curve encryption)

    priv_key = ec.generate_private_key(ec.SECP256K1, default_backend())

    pub_key = priv_key.public_key()

    pub_key_pem = pub_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
        )

    with open('public_key.pem', 'wb') as outfile:
        outfile.write(public_key_pem)

有关加密文档的更多信息:https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/#cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey