`dump_privatekey` truncates key when null byte in passphrase
See original GitHub issueThis shouldn’t be a thing…
import OpenSSL
pk_passphrase = b"12345\x0067890"
truncated_passphrase = pk_passphrase.split(b"\x00", 1)[0]
plain_pk = """-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMcRMugJ4kvkOEuT
AvMFr9+3A6+HAB6nKYcXXZz93ube8rJpBZQEfWn73H10dQiQR/a+rhxYEeLy8dPc
UkFcGR9miVkukJ59zex7iySJY76bdBD8gyx1LTKrkCstP2XHKEYqgbj+tm7VzJnY
sQLqoaa5NeyWJnUC3MJympkAS7p3AgMBAAECgYAoBAcNqd75jnjaiETRgVUnTWzK
PgMCJmwsob/JrSa/lhWHU6Exbe2f/mcGOQDFpesxaIcrX3DJBDkkc2d9h/vsfo5v
JLk/rbHoItWxwuY5n5raAPeQPToKpTDxDrL6Ejhgcxd19wNht7/XSrYZ+dq3iU6G
mOEvU2hrnfIW3kwVYQJBAP62G6R0gucNfaKGtHzfR3TN9G/DnCItchF+TxGTtpdh
Cz32MG+7pirT/0xunekmUIp15QHdRy496sVxWTCooLkCQQDIEwXTAwhLNRGFEs5S
jSkxNfTVeNiOzlG8jPBJJDAdlLt1gUqjZWnk9yU+itMSGi/6eeuH2n04FFk+SV/T
7ryvAkB0y0ZDk5VOozX/p2rtc2iNm77A3N4kIdiTQuq4sZXhNgN0pwWwxke8jbcb
8gEAnqwBwWt//locTxHu9TmjgT8pAkEAlbF16B0atXptM02QxT8MlN8z4gxaqu4/
RX2FwpOq1FcVsqMbvwj/o+ouGY8wwRiK0TMrQCf/DFhdNTcc1aqHzQJBAKWtq4LI
uVZjCAuyrqEnt7R1bOiLrar+/ezJPY2z+f2rb1TGr31ztPeFvO3edLw+QdhzwJGp
QKImYzqMe+zkIOQ=
-----END PRIVATE KEY-----
"""
pkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, plain_pk)
encrypted_pk = OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, pkey, "AES-256-CBC", pk_passphrase
)
decrypted_pk_obj = OpenSSL.crypto.load_privatekey(
OpenSSL.crypto.FILETYPE_PEM, encrypted_pk, truncated_passphrase
)
decrypted_pk = OpenSSL.crypto.dump_privatekey(
OpenSSL.crypto.FILETYPE_PEM, decrypted_pk_obj
).decode()
assert plain_pk == decrypted_pk
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (5 by maintainers)
Top Results From Across the Web
How to Crack SSH Private Key Passwords with John the Ripper
First, we created a new user on the target system and generated an SSH key pair. Next, we obtained the private key from...
Read more >Decrypt a private key encrypted with a null-containing ...
From what I can see, PEM_read_PrivateKey only accepts a null -terminated passphrase, unlike PEM_write_PrivateKey . How is it possible to decrypt ...
Read more >Public key cryptography: OpenSSH private keys
An encryption system needs a key (a sequence of bits used to encrypt the message) and we need to derive it from the...
Read more >Best way to remove bytes from the start of a file?
What's the best way to do this? To start with I tried dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump. but after ...
Read more >pyopenssl/test_crypto.py at main
... KEY-----. """ # certificate with NULL bytes in subjectAltName and common name ... By dumping using the truncated passphrase load should raise...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Ah I see what you’re saying here. pyOpenSSL uses
PEM_write_bio_PrivateKey
andPEM_read_bio_PrivateKey
using thepem_password_cb
for this, which doesn’t allow passing a length (so it computes it via null terminated logic). These functions also take a char * and length though so not sure why it was originally done this way. We’d take a patch to fix this since it’s foolish, but in general our recommendation with these APIs is to usecryptography
where possible (which doesn’t make this mistake).Basically, this MWE shows that if a passphrase contains a null byte and that passphrase is used to dump a PK. Then if you thought you were encrypting with a 32 byte key, you won’t be; you’ll be using however many bytes up to the null byte.
We found this because we managed to generate a random key that had a null byte as the first byte and OpenSSL exploded saying you can’t encrypt with an empty string for a key 😂