Open Dmitry-Frantsev opened 6 years ago
Hi @Dmitry-Frantsev I am not sure what your request is. Do you mean a way to store the private key in the file system? Can you please explain why it is important to store a private key with cipher? IMHO, a cipher is meant for encryption\decryption data. Not to store a private key in the file system.
Hi. I have used openSSL library until now. My program has a file system storage with ecrypted users private keys (PEM format). The program loads the encrypted private key and decrypts it when user is logging in.
MBEDTLS library can load encrypted RSA keys (PEM format). I use mbedtls_pk_parse_key( ) function to load keys. It works perfectly. But function mbedtls_pk_write_key_pem( ) can not save a RSA key with encription.
Could you add encryption support for mbedtls_pk_write_key_pem( ).
Bump!
Mbed TLS supports key wrapping. See https://github.com/ARMmbed/mbedtls/blob/development/include/mbedtls/nist_kw.h
Does this work in your use case? If not, why not?
It can work but a solution that will export in PEM format a passphrase-protected key will be appreciated. Like said before, a function mbedtls_pk_write_key_pem
that will take a passphrase in arguments.
Is there a solution for this? I really need to take use this. There really isn't any other solution for me.
This feature would make sense, but Arm isn't likely to work on it in the foreseeable future. Pull requests welcome.
Is there a solution for this? I really need to take use this. There really isn't any other solution for me.
Some preview of this is available at fork https://github.com/loafer-mka/mbedtls, branch ‘dev_clean’. The last four commits in this branch add new features, and the optional three previous ones slightly adjust the project for older versions of visual studio, gcc and python 3.4.
This is an attempt to add enhanced support for load/store encrypted and plain keys in different formats... there are not tests at all (added/changed functions were tested together with other project which uses mbedtls... so they are working ... it seems to me ;) ) Also I'm not sure about the convenient API... may be some functions may be combined.
Over time, I hope to add tests and refine the pull request, but it will take time.
If you can check and suggest a better API, then that would be great.
Questions and wishes are welcome. Andrey Makarov, mka-at-mailru@mail.ru
What is missing in MBed TLS is support (in the form of utility functions) for writing PKCS#8 formatted private keys. I think this is what most people colloquially refer to as "PEM formatted" private keys. A better title for this issue would be "Add support for writing encrypted PKCS#8 keys".
Note that MBed TLS already has features for converting ASN.1 DER data to PEM (mbedtls_pem_write_buffer
). However, it is missing easy ways to encrypt private keys and store the encrypted keys in a standard format. Personally, I prefer to keep keys in DER format on (typically memory / CPU constrained) systems using MBed TLS.
Currently the only way to (somewhat easily) create encrypted private keys in MBed TLS is using the PKCS#5 format, with mbedtls_pkcs5_pbes2
([mbedtls_pkcs5_pbes2_ext
](https://mbed-tls.readthedocs.io/projects/api/en/development/api/file/pkcs5_8h/?highlight=mbedtls_pkcs5_pbes2#_CPPv423mbedtls_pkcs5_pbes2_extPK16mbedtls_asn1_bufiPKh6size_tPKh6size_tPh6size_tP6size_t in newer versions)).
However, this has some downsides:
So it should be possible to create a "PEM PKCS#8 encrypted private key" in MBedTLS, which is the default private key format for tools like OpenSSL, but it's far from convenient, requiring the following steps:
mbedtls_rsa_gen_key
)mbedtls_pkcs5_pbes2
mbedtls_pem_write_buffer
This is in stark contrast to the easy of use of the private key parsing function mbedtls_pk_parse_key
and writing utility functions like mbedtls_x509write_cert and mbedtls_x509write_csr.
@seppestas Thanks for the feedback! Work on features such as this one is unfortunately paused while we prepare the next major version of Mbed TLS, and we'll need to expand the API to cover encrypted key formats which will likely land after 4.0. So this is on our radar, but won't happen soon.
I eventually settled on using a plain AES cypher to encrypt private keys iof. mbedtls_pkcs5_pbes2
. 2 reasons for this:
mbedtls_pkcs5_pbes2
is kind of broken, possibly in an insecure way, even when used for decryption. This was only fixed recently in Mbed TLS 3.5.0 : https://github.com/Mbed-TLS/mbedtls/blob/development/ChangeLog#L323-L327.Either way, my application has fairly little benefit from thing like PBKDF.
I still think it should be possible to use mbedtls_pkcs5_pbes2_ext
for generating PKCS#8 format encrypted private keys, but it's quite a pain. I think what @loafer-mka mentions in his fork
Note: mbedtls_pkcs5_pbes2() cannot be used for encrypting key: it does not return [the] actual length of encrypted data after padding, so we cannot assign OCTET_STRING length after encryption. Moreover: best way is to pad buffer manually and disable padding by cipher because mbedtls_cipher_crypt() (like as mbedtls_cipher_update()) cannot pad if in-place encrypting (input buffer == output buffer) used.
Can be overcome by reserving space (at least one block size) for the padding and calculating the expected padding size (and thus cyphertext size) based on the cypher block size.
Though I never got it working fully and lost interest in getting it working when I realised mbedtls_pkcs5_pbes2
isn't safe in my version of Mbed TLS.
Wanted to note that @seppestas workaround seems do-able in version 3.6.0. I have verified it by modifying the gen_key
program to encrypt the key using a password:
https://github.com/morningstarcorp/mbedtls-morningstar/tree/experimental/gen_pkcs5_enc_key
The resulting key can be parsed by openssl
without issue.
(please note that in my example I hard-code the salt and IV for ease of debugging, it's intended only as an example of constructing the ASN.1 structure properly)
Description
Priority: Major
Enhancement\Feature Request
Add support a cipher for storing private keys please. I use mbedtls library for RSA key pair generation. It is very important to store a private key with cipher.