In pyOpenSSL i haven't been able to find a way to encrypt a RSA private key with AES 256 just yet, been looking all over the place for this but cant seem to find a way.
Before i used OpenSSL to get the key and ca/cl certificates but now im opting to make an application where i need to handle the pfx-file in certain ways.
In OpenSSL i used to do the following:
openssl pkcs12 -in file.pfx -nocerts -out key.key
after that i did:
openssl rsa -aes256 -key.key -out encrypted.key
is there anything similar in pyOpenSSL using crypto?
I believe I solved this. But for anyone wondering, this is what I did:
import os
import shutil
from Crypto.PublicKey import RSA
def encrypt(old_key, new_key, passphrase):
key = RSA.importKey(open(old_key, 'rb').read())
with open(new_key, 'wb') as f:
pem_key = key.export_key(format='PEM', passphrase=passphrase, pkcs=8, protection='PBKDF2WithHMAC-SHA1AndAES256-CBC')
f.write(pem_key)
f.close()
if os.path.exists(old_key):
os.remove(old_key)
encryptAES('path_to_old_key', 'path_to_new:key.key', 'supersecretpassword')
One question still remaining is if there's anyway to output the encryption info done in python similar to OpenSSL?
If you run openssl rsa -aes256 -in old.key -out new.key
The key will return attributes in the beginning like such:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC
Key here...
-----END RSA PRIVATE KEY-----
However when I export the private key in Python I just get:
-----BEGIN ENCRYPTED PRIVATE KEY-----
Key here...
-----END ENCRYPTED PRIVATE KEY-----
Is there anyway to display these attributes with pycryptodome?
Related
I am integrating with EBS-EDT SOAP which uses wsse. I can successfully send XML envelope and receive an encrypted response. As I am making use of custom python code I decide I would manually try to decrypt the response first before implementing the wrapper code.
Based on the spec the following happens
Encryption key is encrypted with the public key from the original request contained in EncryptedKey tag.
This stage needs to be decoded as its base64.
This encryption key is then used in an AES 128 encryption to decrypt the XML body content.
P.S I looked at this blog with code snippets(not in python) and the process seems the same as what I am doing (http://webservices20.blogspot.com/2013/12/consuming-ebs-edt-soap-service-from-wcf.html)
I wrote the following python code snippet to decode the encryption key, but keep getting an error ValueError: Ciphertext with incorrect length (not 512 bytes). I am guessing it has to do with padding or that the certificate key use isn't correct, but unfortunately, the spec doesn't indicate what the padding would be and I have tried multiple key usages with no success.
My decryption code sample
import base64
from Cryptodome.Cipher import PKCS1_v1_5
from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
private_key_pem = "-----BEGIN PRIVATE KEY-----
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
PURtfoyDKlUpHmoJ+ruyu0bHpE4W
-----END PRIVATE KEY-----"
s = "gJvJjWEsmTcGzDvmYhVsheWR234xfo6lXx+cJCsTTy6tUwSBR+l5qqEFVpGohiSJhwa5IsRBDiJ28dOOnz0T6J3MSq82q34R0n8hJ80Hz37HL4KlVsygcdGceDbSYsIrPQRrMKTc2HB79r8/CqnQw2K5e71Gkw44soEtyzeldQ5hQFtsGkM1jkA40Xdu7mAjzUQ1REAVvR1fb0nLi6LRPZq+wnfMajLy1+8y+pCcQpsFBA5BD8j8EgHCLnpQE6GiRE6CLQNOa3s8/bnF1iGDfpJzAT8qJWZVpfQ4SuAhS6HRLe/TpXe5cDXnbWZxtkjMggAvkhR18bVXC8F0Pg81lQ=="
code_bytes = s.encode('UTF-8')
print(s)
print(code_bytes)
by = base64.b64decode(code_bytes)
print(by)
print(len(by))
private_key = RSA.import_key(private_key_pem)
cipher = PKCS1_v1_5.new(private_key)
sentinel = get_random_bytes(16)
#rsadecrypt = cipher.decrypt(by[3: 3 + 256], sentinel)
rsadecrypt = cipher.decrypt(by, sentinel)
if rsadecrypt == sentinel:
print('failure')
else:
print(f'success: {rsadecrypt.hex(" ")}')
For completeness here is the commands I use to generate the server keys used for xml encryption.
openssl x509 -req -sha256 -extfile x509.ext -extensions ca -in CA.csr -signkey CA.key -days 1095 -out CA.pem
openssl req -new -sha256 -nodes -newkey rsa:4096 -keyout ohip.key -out ohip.csr
openssl x509 -req -sha256 -CA CA.pem -CAkey CA.key -days 730 -CAcreateserial -CAserial CA.srl -extfile x509.ext -extensions server -in ohip.csr -out ohip_crt.pem```
In addition to this thread: Where is the trust chain? [python] asn1crypto and pkcs11 Aladdin USB eToken
I tried:
openssl x509 -pubkey -noout -in cert.pem
Error getting public key
140003854860736:error:0D0680A8:asn1 encoding routines:asn1_check_tlen:wrong tag:../crypto/asn1/tasn_dec.c:1129:
140003854860736:error:0D06C03A:asn1 encoding routines:asn1_d2i_ex_primitive:nested asn1 error:../crypto/asn1/tasn_dec.c:693:
140003854860736:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:626:Field=n, Type=RSA
140003854860736:error:0408B004:rsa routines:rsa_pub_decode:RSA lib:../crypto/rsa/rsa_ameth.c:51:
140003854860736:error:0B09407D:x509 certificate routines:x509_pubkey_decode:public key decode error:../crypto/x509/x_pubkey.c:124:
The contents of this file is:
-----BEGIN CERTIFICATE-----
MIIFXjCCBEigAwIBAQIEBHHhkjALBgkqhkiG9w0BAQswKjEoMCYGA1UEAwwfTW92
aW1lbnRvIEVzdHVkYW50aWwgQnJhc2lsZWlybzAiGA8yMDE5MDEwMTAwMDAwMVoY
DzIwMjAwMzMxMjM1OTU5WjAWMRQwEgYDVQQDDAtDTkUgVEVTVEUgMzCCAjgwCwYJ
KoZIhvcNAQEBA4ICJwAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCd
YHeqD8rwL2AtAeX1CLVxVP3LF9sjRDlSY6/0nrkr+WxNICHP5FI6GFTTLlHvgkwW
P4JKCIsEe6q+w7KfY5/BUy5wC65+o9bG25KA+MrUyN1h1Lonn8/6AKb/h+cz7MI9
yalMl2iu28zeQJHNzzRVM0W9/lG7WANn14pwQHsMa6WYnRl9APoqAvvqj6tOgD04
qPUlkgQRhGYJizgB6ZHR4TVAGj/TCV0XEPZOJIpTrd7nsET+xCjMjBg8jT3qg7Vg
lghIn+72Yi0nKykmN5duZwlvcFTfKkNBvJicDExYZ7WXxu9PfJETdHyFQLLck+Cr
MlSDloI/K9qWfdd8iX6GzETspfPV+ZXkdvfIM8A4TdlCiVx5n+1xc6jk4NB5eHSu
S80oNO0ctg6qKBcHb8YwV5VnQFZE3WaOZTORUBq+bjQxci9g0MA7ZqTK0O0K1QOL
Gl38AbDFjHpdtLIl/LdmzhSFx3NR4lA8RE4AkMOOeNqcDrRT4/PlBWoPsqWYcpPL
6AGl0I8N6hrm1iOvIxTWU6zV40E4SJSViPNzlo3L5iK+Ej4G3/YSCB8850nc6j11
3QGUTUvX8a8ZoKE3BuCO3LtYWYAb/RxyGlCq9jMFwHTYqqHu9cA5CwilMfP31SZ4
bMKhwR2AI/iowcMqCVtSZYi/dUDk9wY89nqY+5I+7QIDAQABo4IBiDCCAYQwRgYF
YEwBCgEEPTE5OTgtMDMtMTY2NzE0ODUyNDYwMTAwNzQ0NjQyMjU2NTIzNTAwMDAw
MDAwMDAwMDAwMDAwMDAwMDAwMDAwQwYFYEwBCgIEOlVuaXZlcnNpZGFkZSBDYW5k
aWRvIE1lbmRlc1N1cGVyaW9yRGlyZWl0b1JpbyBkbyBKYW5laXJvUkowIgYFYEwB
BAMEGUx1aXMgSW5hY2lvIEx1bGEgZGEgU2lsdmEwYgYIKwYBBQUHAQEEVjBUMFIG
CCsGAQUFBzAFhkZodHRwczovL3ZhbGlkYS5zb3BhZ29tZWlhLmNvbS5ici9nZXRf
YXV0aG9yaXR5X2luZm9ybWF0aW9uX2FjY2Vzcy83NDU3MDgGA1UdHwQxMC8wLaAr
oCmGJ2h0dHBzOi8vZG9taW5pby5jb20vZ2V0X2NybC9jb2RpZ29fZWVhLzAzBgNV
HSMELDAqgCg4OGQwZGU4MmMxYzE4NjJlZjUzYjExMWIwMzE2ODRlYWE1YjAwM2Ri
MAsGCSqGSIb3DQEBCwOCAQEAAhxXh4ouoo3pv12/nYyIKWDNDuRdAXCVasAQtpn6
ZOfOzde1a2AnqMET04BrR5SSpBeBq+aVacXtIVQCPoBD7F8+NppEM+q/Gw8aGugP
dXGKTgMQZMGI1vHMsydNB3tg0MoepUyr3V6HmBSGQkRq8uLiQ2Ke3Fm6/I+BOdNl
oe6/VBcD3zOMM+qnqM/ucR2Lcje0deifGTVnP16bISBk8077PxzGq1Ds2jLrDj1+
KsVA4JKBCZgDT3BBCQrKbXnENDeCSZ9TVlzgcNBFnFQzWDga3UjLvhEj8SjSg9Rl
e1jK7e83C6A96ixfUDlD6pVPl57QHAaalnQ6aHONq2wamg==
-----END CERTIFICATE-----
What's wrong with this file or with the code from that thread? I can't extract the public key.
I generated a self-siged certificate like so:
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365
The file cert.pem contains my public key. I wish to extract this public key from this file.
The way I tried to do is:
f = open('cert.pem', "rb")
pem_data = f.read()
f.close()
print(pem_data)
key = serialization.load_pem_public_key(pem_data, backend=default_backend())
However, after running the code, I get this error:
ValueError: Could not deserialize key data.
As a result I unable to extract the public key.
How do I fix this in order to extract the public key?
Note in the document
A PEM block which starts with -----BEGIN CERTIFICATE----- is not a public or private key, it’s an X.509 Certificate. You can load it using load_pem_x509_certificate() and extract the public key with Certificate.public_key.
Just try this:
from cryptography.hazmat.backends import default_backend
from cryptography import x509
f = open('cert.pem', "rb")
pem_data = f.read()
f.close()
key = x509.load_pem_x509_certificate(pem_data, backend=default_backend())
public_key = key.public_key()
In the first place check cryptography library is installed if it's no like that so:
pip install cryptography
You have to create your RSA keys with OpenSSL:
openssl genrsa -out jwt-key 4096
openssl rsa -in jwt-key -pubout > jwt-key.pub
reference : enter link description here
I used a GUI tool to make a X509 certificate and tried to use M2Crypto of Python to extract useful information from that cert, but came across issues. Code as below:
ca=X509.load_cert("MyCA.crt", X509.FORMAT_PEM)
print ca_pub.as_pem(cipher=None)
-----BEGIN PRIVATE KEY-----
MIIBJwIBADANBgkqhkiG9w0BAQEFAASCAREwggENAgEAAoIBAQDol4gW9mDc8IRW
Ack4Y0/Nk+OnikJPMj65YDIexVuW/ptCEnRAX+EZmB3lM4labS0Ou5gydKj3vpoR
dUM6Un1d8YYyw8Q2gJGXDHbTFjn/eU98VxIa7nHYlZGLvG5g0Eo4fCTUw3CBhI3Y
B8U3C89Ez1IL6sqly9Fhc5BICFtxVtCngWhapR3tIcR85h3vlUCmavhRyBmtdiku
As6ceH9GxfaFmONph/GzKVHy7iA6MSAIf/EDyz5jRKfWwhLQh4Uq9BWfioaFlQPF
iZlxs45iE3pAxrAAejkguUrjeAmIojQvQq9T0YNtdf3LQCUVn2Vfd9KkqncqADew
tujidoEZAgMBAAE=
-----END PRIVATE KEY-----
My questions:
Why get_pubkey() displays "Private Key" information? Should it begin with ---Begin Public Key ----- ?
The certificate is self-signed, and how to get the digital signature from the certificate?
Many thanks!!
I have not found a way to load an RSA private key from a PEM file to use it in python-crypto (signature).
python-openssl can load a PEM file but the PKey object can't be used to retrieved key information (p, q, ...) to use with Crypto.PublicKey.construct().
I recommend M2Crypto instead of python-crypto. You will need M2Crypto to parse PEM anyway and its EVP api frees your code from depending on a particular algorithm.
private = """
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMPFZQ7Ic+BmmeWHvvVP4Yj
yu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQJAIHCz8h37N4ScZHThYJgt
oIYHKpZsg/oIyRaKw54GKxZq5f7YivcWoZ8j7IQ65lHVH3gmaqKOvqdAVVt5imKZ
KQIhAPPsr9i3FxU+Mac0pvQKhFVJUzAFfKiG3ulVUdHgAaw/AiEA3ozHKzfZWKxH
gs8v8ZQ/FnfI7DwYYhJC0YsXb6NSvR8CIHymwLo73mTxsogjBQqDcVrwLL3GoAyz
V6jf+/8HvXMbAiEAj1b3FVQEboOQD6WoyJ1mQO9n/xf50HjYhqRitOnp6ZsCIQDS
AvkvYKc6LG8IANmVv93g1dyKZvU/OQkAZepqHZB2MQ==
-----END RSA PRIVATE KEY-----
"""
message = "python-crypto sucks"
# Grab RSA parameters e, n
from M2Crypto import RSA, BIO
bio = BIO.MemoryBuffer(private)
rsa = RSA.load_key_bio(bio)
n, e = rsa.n, rsa.e
# In Python-crypto:
import Crypto.PublicKey.RSA
pycrypto_key = Crypto.PublicKey.RSA.construct((n, e))
# Use EVP api to sign message
from M2Crypto import EVP
key = EVP.load_key_string(private)
# if you need a different digest than the default 'sha1':
key.reset_context(md='sha256')
key.sign_init()
key.sign_update(message)
signature = key.sign_final()
# Use EVP api to verify signature
public = """
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANQNY7RD9BarYRsmMazM1hd7a+u3QeMP
FZQ7Ic+BmmeWHvvVP4Yjyu1t6vAut7mKkaDeKbT3yiGVUgAEUaWMXqECAwEAAQ==
-----END PUBLIC KEY-----
"""
from M2Crypto import BIO, RSA, EVP
bio = BIO.MemoryBuffer(public)
rsa = RSA.load_pub_key_bio(bio)
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)
pubkey.reset_context(md="sha256")
pubkey.verify_init()
pubkey.verify_update(message)
assert pubkey.verify_final(signature) == 1
See http://svn.osafoundation.org/m2crypto/trunk/tests/test_rsa.py, but I prefer using the algorithm-independent EVP API http://svn.osafoundation.org/m2crypto/trunk/tests/test_evp.py.
How do you verify an RSA SHA1 signature in Python? addresses a similar issue.
is this (close to) what you tried doing?
public_key_filename = 'public_key.pem'
rsa = M2Crypto.RSA.load_pub_key(pk)
That should work. The issue might be with openssl too, does it work when you just use openssl (not in Python)?
Link to Me Too Crypto