我目前正在尝试编写一个脚本,允许我从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调用不同的输出。 这只是一个允许不同结果的实施问题吗?或者我在某处犯了错误?
任何帮助将不胜感激
答案 0 :(得分:4)
首先我们加载文件
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)