RustCrypto / RSA

RSA implementation in pure Rust
Apache License 2.0
550 stars 153 forks source link

Verifying RSA Signature with OpenSSL #372

Closed mettke closed 1 year ago

mettke commented 1 year ago

I'm trying to create a signature using RSA and SHA-1 in rust which can be verified using openssl. However, so far I was not able to find out how to do this.

When I run this code using openssl for signing and verifying then it works:

let private_key: RsaPrivateKey = ...;
let policy: String = "";

// Convert Key to OpenSSL
let key = private_key
    .to_pkcs8_pem(base64ct::LineEnding::CRLF)
    .expect("Unable to export");
let key = openssl::pkey::PKey::private_key_from_pem(key.as_bytes()).expect("Unable to import");

// Create Signature
let mut signer = openssl::sign::Signer::new(openssl::hash::MessageDigest::sha1(), &key)
    .expect("Unable to create signer");
signer.update(policy.as_bytes()).expect("Unable to update");
let data = signer.sign_to_vec().expect("Unable to sign");

// Verify 
let mut verifier = openssl::sign::Verifier::new(openssl::hash::MessageDigest::sha1(), &key)
    .expect("Unable to create verifier");
verifier
    .update(policy.as_bytes())
    .expect("Unable to add policy");
assert!(verifier.verify(&data).expect("Unable to verify"), "Signature invalid");

However, when I replace the signature creation part with this crate then it fails validation:

let private_key: RsaPrivateKey = ...;
let policy: String = "";

// Convert Key to OpenSSL
let key = private_key
    .to_pkcs8_pem(base64ct::LineEnding::CRLF)
    .expect("Unable to export");
let key = openssl::pkey::PKey::private_key_from_pem(key.as_bytes()).expect("Unable to import");

// Create Signature
use rsa::signature::{SignatureEncoding, Signer};
let signing_key = rsa::pkcs1v15::SigningKey::<sha1::Sha1>::new_unprefixed(private_key.clone());
let data = signing_key
    .sign(policy.as_bytes())
    .to_vec();

// Verify 
let mut verifier = openssl::sign::Verifier::new(openssl::hash::MessageDigest::sha1(), &key)
    .expect("Unable to create verifier");
verifier
    .update(policy.as_bytes())
    .expect("Unable to add policy");
assert!(verifier.verify(&data).expect("Unable to verify"), "Signature invalid");

Is there a configuration option that I'm missing?

tarcieri commented 1 year ago

I think the issue is here:

rsa::pkcs1v15::SigningKey::<sha1::Sha1>::new_unprefixed

You probably need to use:

rsa::pkcs1v15::SigningKey::<sha1::Sha1>::new

And if that's the reason, I'm curious why you used new_unprefixed in the first place. Was there some documentation that suggested it?

tarcieri commented 1 year ago

Please reopen if switching from new_unprefixed to new does not solve your problem

mettke commented 1 year ago

Thanks for the tip. However unfortunatly this does not solve the issue as it does not seem to be possible to use new with sha1

error[E0599]: the function or associated item `new` exists for struct `SigningKey<CoreWrapper<Sha1Core>>`, but its trait bounds were not satisfied
   --> lib/cloudflare_signer/src/lib.rs:128:64
    |
128 |     let signing_key = rsa::pkcs1v15::SigningKey::<sha1::Sha1>::new(private_key.clone());
    |                                                                ^^^ function or associated item cannot be called on `SigningKey<CoreWrapper<Sha1Core>>` due to unsatisfied trait bounds
    |
   ::: /home/signum/.cargo/registry/src/index.crates.io-6f17d22bba15001f/digest-0.10.7/src/core_api/wrapper.rs:24:1
    |
24  | pub struct CoreWrapper<T>
    | ------------------------- doesn't satisfy `_: AssociatedOid`
    |
    = note: the following trait bounds were not satisfied:
            `sha1::digest::core_api::CoreWrapper<sha1::Sha1Core>: rsa::pkcs8::AssociatedOid`
mettke commented 1 year ago

And I do not seem to have the permission to reopen 😅

tarcieri commented 1 year ago

Enable the oid feature of the sha1 crate.

It will be on-by-default in the next release.

mettke commented 1 year ago

Ah I see. It works now thanks. I expected that this was not implemented to do other reasons and did not consider it being a feature 😅 .

Thanks for the quick help 😌