Currently, when calling RsaPrivateKey.to_pkcs8_encrypted_pem(), it seems to use the scrypt crate's default parameters, which are: n=32768, r=8, p=1, len=32. Unfortunately, openssl can't load these files and fails with:
❯ openssl rsa -in /tmp/test.key
Enter pass phrase for /tmp/test.key:
Could not read private key from /tmp/test.key
001E5B249B7F0000:error:030000AC:digital envelope routines:scrypt_alg:memory limit exceeded:providers/implementations/kdfs/scrypt.c:482:
001E5B249B7F0000:error:030000AB:digital envelope routines:PKCS5_v2_scrypt_keyivgen_ex:illegal scrypt parameters:crypto/asn1/p5_scrypt.c:260:
Looking at openssl's manpage, it seems that they default to a lower n value:
-scrypt
Uses the scrypt algorithm for private key encryption using default parameters: currently N=16384,
r=8 and p=1 and AES in CBC mode with a 256 bit key. These parameters can be modified using the
-scrypt_N, -scrypt_r, -scrypt_p and -v2 options.
Currently, I'm able to match that and create openssl-compatible key files with:
let key: &RsaPrivateKey = <...>;
let mut rng = rand::thread_rng();
let mut salt = [0u8; 16];
rng.fill_bytes(&mut salt);
let mut iv = [0u8; 16];
rng.fill_bytes(&mut iv);
// 14 = log_2(16384), 32 bytes = 256 bits
let scrypt_params = scrypt::Params::new(14, 8, 1, 32).unwrap();
let pbes2_params = pbes2::Parameters::scrypt_aes256cbc(scrypt_params, &salt, &iv).unwrap();
let plain_text_der = key.to_pkcs8_der().unwrap();
let private_key_info = PrivateKeyInfo::try_from(plain_text_der.as_bytes()).unwrap();
let secret_doc = private_key_info.encrypt_with_params(pbes2_params, passphrase).unwrap();
let encrypted_pem = secret_doc.to_pem(EncryptedPrivateKeyInfo::PEM_LABEL, LineEnding::LF).unwrap();
pkcs8's defaults are more secure, so I don't think they should be changed, but could a more convenient API for specifying the parameters be added? (or does such a thing already exist?)
Thanks!
Currently, when calling
RsaPrivateKey.to_pkcs8_encrypted_pem(), it seems to use the scrypt crate's default parameters, which are: n=32768, r=8, p=1, len=32. Unfortunately, openssl can't load these files and fails with:Looking at openssl's manpage, it seems that they default to a lower
nvalue:Currently, I'm able to match that and create openssl-compatible key files with:
pkcs8's defaults are more secure, so I don't think they should be changed, but could a more convenient API for specifying the parameters be added? (or does such a thing already exist?)
Thanks!