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```
Related
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?
I'm trying to generate the same SHA1 fingerprint for a X509 certificate using pycryptodome that I get from the openssl command:
openssl x509 -noout -fingerprint -sha1 -inform pem -in certificate.crt
My certificate is in PEM format on disk
However, the code snippet below gives me a different value.
from Crypto.PublicKey import RSA
import hashlib
contents = open("/home/ubuntu/certificate.crt", "r").read().encode()
certificate = RSA.import_key(contents)
bytes = certificate.export_key("DER")
hashlib.sha1(bytes).hexdigest()
Anyone any idea what I'm doing wrong?
Still don't know how to do it using Pycryptodome, but I found there's no need for it at all. The following code fragment generates the same fingerprint as openssl does
pem = open("/home/ubuntu/certificate.crt", "r").read().encode()
pem = pem.removeprefix("-----BEGIN CERTIFICATE-----\n")
pem = pem.removesuffix("-----END CERTIFICATE-----\n")
public_bytes = base64.b64decode(pem)
sha1digest = hashlib.sha1(public_bytes).hexdigest()
fingerprint = ":".join(sha1digest[i : i + 2] for i in range(0, len(sha1digest), 2))
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 did a Google search but I didn't find anything that would help me on that.I'm trying to authenticate my app in Microsoft Azure, so I created some self signed certificates. They give a tutorial of how to parse the crt however it's in PowerShell. I use only Ubuntu / OS X. Here's the code:
$cer = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cer.Import("mycer.cer")
$bin = $cer.GetRawCertData()
$base64Value = [System.Convert]::ToBase64String($bin)
$bin = $cer.GetCertHash()
$base64Thumbprint = [System.Convert]::ToBase64String($bin)
$keyid = [System.Guid]::NewGuid().ToString()
How would I go about writing the same code in Python? I have the .crt, .key, .csr, .pass.key and pkcs8_key files.
Update:
I want to extract the keyId and customKeyIdentifier from the certificates.
#philippe,
According to your description, if you want to get the certificate information using python, please refer to this simple code. I used the .cer as testing file:
import OpenSSL.crypto
f=open("tested.cer", "rb")
der = f.read()
x509=OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, der)
print("serial number",x509.get_serial_number());
print("Issue Name",x509.get_issuer());
print("subject_name_hash",x509.subject_name_hash());
idif=x509.get_extension(0)
print("extension",x509.get_extension(0))
print("id",idif.get_data(),idif.get_short_name())
print("get_subject",x509.get_subject());
pkey = x509.get_pubkey()
print("Public Key ",pkey)
listdir=dir(pkey)
print(listdir)
print(pkey.bits())
print(pkey.type())
print(pkey._pkey)
Meanwhile, if you want to get a certificate information as keyId and customKeyIdentifier , I recommend you refer to the define of these properties of certificate and this sample. You can find the corresponding properties on that page. With these properties, you can get your certificate and its extension information. And you also can refer to this API documents. If I misunderstood, please feel free to let me know.
You don’t need neither python or powershell to parse certificates for Microsoft Azure.
The documentation describe 3 properties that are needed :
"keyCredentials": [
{
"customKeyIdentifier": "$base64Thumbprint_from_above",
"keyId": "$keyid_from_above",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"value": "$base64Value_from_above"
}],
$base64Thumbprint is the base64 encoding of the sha1 hash of the certificate (in der format)
$keyid is just a random guuid
$base64Value is the base64 encoding of the whole certificate (in der format)
Generate the certificate
To generate a self-signed certificate (x509 with rsa 2048)
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt
Compute the base64 thumbprint
$ openssl x509 -outform der -in certificate.crt | openssl dgst -binary -sha1 | openssl base64
Compute the base64
$ openssl x509 -outform der -in certificate.crt | openssl base64 -A
Generate a random uuid
$ python -c "import uuid; print(uuid.uuid4())"
I checked against results generated with powershell and there are the same