RustCrypto/RSA

How to construct rsa::RsaPrivateKey from PEM?

FssAy opened this issue · 5 comments

FssAy commented

I have a private RSA key in a PEM format that I need to use with Pkcs1v15Sign to sign a specific digest.

I was able to decode the private key with RsaPrivateKey::from_pem(&private_key) , but then I've noticed the Pkcs1v15Sign::sign method requires other struct with the same name which is documented as a "whole RSA key, public and private parts", but I've found no possible way to construct it from an existing pair, only to generate a new random one.

Am I missing something, or is it the desired behavior?

image

You need to use RsaPrivateKey::sign:

let rsa_pv = RsaPrivateKey::from_pem(...);
let pkcs1_15 = Pkcs1v15Sign::new::<sha2::Sha256>();
let signature = rsa_pv.sign(pkcs1_15, hashed)?;

...or create a pkcs1v15::SigningKey: https://docs.rs/rsa/latest/rsa/#pkcs1-v15-signatures

FssAy commented

Thank you for the help, but the sign method was not found in the RsaPrivateKey.

image

I've imported a trait that the compiler suggested, but the sign method implemented there accept only one argument which is a &[u8]

image

I've also tried to create the pkcs1v15::SigningKey, but the same issue appears.

image

How are you creating the key?

I'm guessing that's pkcs1::RsaPrivateKey or something?

As I guess you're asking about, you need to use rsa::RsaPrivateKey. Here's some documentation on PKCS#1 encoding:

https://docs.rs/rsa/latest/rsa/#pkcs1-rsa-key-encoding

You'll want to use pkcs1::DecodeRsaPrivateKey::from_pkcs1_pem if the key is encoded as PKCS#1.

FssAy commented

[solved, no need to read further, thaks]

I am getting it from a third-party service (Firebase Cloud Messaging) in PEM format in order to make a JWT token and sign it with RS256 algorithm. I realy wanted to avoid use of the jwt crate and got stuck only on constructing the RsaPrivateKey from the obtained PEM encoded private key.

Here is what the third-party documentation mentioned:

Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google API Console

So that's why I thought to decode the private key into pkcs1::RsaPrivateKey and then use the Pkcs1v15Sign to compute the signature of the token, but the issue appeared when the Pkcs1v15Sign::sign did not accept the pkcs1::RsaPrivateKey, but only the rsa::RsaPrivateKey which was somewhat confusing. Not to mention that the crate documentation says the rsa::RsaPrivateKey is "a RSA key with public and private pair", but there is no easy way to construct it with that pair (I think).

Hmm, you are right, I didn't notice that in the docs, but I should use the pkcs8....
I've decoded the PEM private key by using:

 rsa::pkcs8::DecodePrivateKey::from_pkcs8_pem(&pk.private_key)?;

and it works perfectly. Thank you very much!