I have a problem decrypting a generated JWK generated by an IBM product. In particular have a look at my example:
JWE: eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTI1NktXIiwiY3R5IjoiSldUIn0.5Dx7B_0XI8F2ZZzkHjiJkeNsw11LlOuMzln9Z6OuGCAMpLeCOXnnPw.VEV_6HmnlroYO483zJdHFw.jS97NRZaPQfO46J9UvG9YsQ0po2SnUJuCe7M9VNIghD8lyUgdqaGx6xXH6MnAD01VLbjYROwh0z8CFGQ5PbamoiNxzMGM3UHDqvKU4j1pdRkcyPZbyZ6oo-NtY5dlwT6FhMMgu3kk7JKaFKXz0mhyNnvx22QTHKWHpMReEuc4AwdeDBL47iX8kT9cyqBzlGWKl-jLvEM73gUzPLC8RxG9_mtyIzEqyiGWtbDavD4yqf7lgo39jBIvwBu-VDVW05A.o15bGBayvRp9Dgzlqd2WAw
JWK: { "alg": "A256KW", "kty": "oct", "use": "enc", "k": "hD-S5Ll-StGTM6K0N891J3KdAgLVdUNRuKCpiweXJh8", "kid": "test"}
Now, this is my Python3 code:
import base64
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.keywrap import aes_key_unwrap
encrypted_jwe = ('eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiQTI1NktXIiwiY3R5IjoiSldUIn0'
'.5Dx7B_0XI8F2ZZzkHjiJkeNsw11LlOuMzln9Z6OuGCAMpLeCOXnnPw.VEV_6HmnlroYO483zJdHFw'
'.jS97NRZaPQfO46J9UvG9YsQ0po2SnUJuCe7M9VNIghD8lyUgdqaGx6xXH6MnAD01VLbjYROwh0z8CFGQ5PbamoiNxzMGM3UHDqvKU4j1pdRkcyPZbyZ6oo-NtY5dlwT6FhMMgu3kk7JKaFKXz0mhyNnvx22QTHKWHpMReEuc4AwdeDBL47iX8kT9cyqBzlGWKl-jLvEM73gUzPLC8RxG9_mtyIzEqyiGWtbDavD4yqf7lgo39jBIvwBu-VDVW05A.o15bGBayvRp9Dgzlqd2WAw')
jwk = {
"kty": "oct",
"k": "hD-S5Ll-StGTM6K0N891J3KdAgLVdUNRuKCpiweXJh8"
}
parts = encrypted_jwe.split('.')
if len(parts) != 5:
print("invalid JWE")
exit(1)
header, encrypted_key, iv, ciphertext, tag = parts
cek_encrypted = base64.urlsafe_b64decode( encrypted_key + '=' * (-len(encrypted_key) % 4))
cek_key = base64.urlsafe_b64decode(jwk['k'] + '=' )
cek = aes_key_unwrap(cek_key, cek_encrypted)
print("decrypted CEK:", cek)
decoded_ciphertext = base64.urlsafe_b64decode(ciphertext + '=' * (-len(ciphertext) % 4))
decoded_iv = base64.urlsafe_b64decode(iv + '=' * (-len(iv) % 4))
cipher = Cipher(algorithms.AES(cek), modes.CBC(decoded_iv), backend=default_backend())
decryptor = cipher.decryptor()
decrypted_payload = decryptor.update(decoded_ciphertext) + decryptor.finalize()
print("decrypted Payload:", decrypted_payload)
Technically speaking i think I need to do the following steps:
- Base64Decode of the k value of my JWK object
- Base64Decode of the encrypted CEK and decryption using A256KW with the key obtained from (1)
- With the now decrypted CEK creating an AES128CBC Decryptor in order to decrypt the Base64Decode of the ciphertext using the decoded IV provided with the JWE
However this code produces an error:
cryptography.hazmat.primitives.keywrap.InvalidUnwrap
What am I doing wrong?
I would need a baseline of a python script capable of doing this job.
Thank you