rpgp / rpgp

OpenPGP implemented in pure Rust, permissively licensed
https://docs.rs/pgp
Apache License 2.0
738 stars 73 forks source link

Seperate digest code and hardcode hash algorithm back in Signature packet when use pgp for sign? #225

Open TommyLike opened 1 year ago

TommyLike commented 1 year ago

Background: We use pgp for remote sign of binaries(all of the sign operation will be performed at server side)

Now when using pgp crate for binary sign, the functional code would be like:

let sig_cfg = SignatureConfig {
            version: SignatureVersion::V4,
            typ: SignatureType::Binary,
            pub_alg: self.public_key.primary_key.algorithm(),
            hash_alg: HashAlgorithm::SHA2_256,
            issuer: Some(self.secret_key.key_id()),
            created: Some(now),
            unhashed_subpackets: vec![],
            hashed_subpackets: vec![
                Subpacket::SignatureCreationTime(now),
                Subpacket::Issuer(self.secret_key.key_id()),
            ],
        };
        let read_cursor = Cursor::new(content);
        let signature_packet = sig_cfg
            .sign(&self.secret_key, passwd_fn, read_cursor)
            .map_err(|e| Error::SignError(self.identity.clone(), e.to_string()))?;

My question is could I seperate the hash logic out of sign function and hardcode the real hash algorithm back into Signature packet? the whole process would be like:

file -> read binary-> perform specified hash algorithm -> digest ->http request from client to server-> pgp sign with none algorithm -> construct signature packet with hash algorithm used in step2.
dignifiedquire commented 1 year ago

What benefit do you expect from that? Is hashing an actual performance bottleneck?

TommyLike commented 1 year ago

@dignifiedquire if we could hashing the object at the client side , there would be no need to transfer the whole object to server which is our case specifically.

hko-s commented 7 months ago

OpenPGP signature hashes consist not only of the hashed payload of the signed data. The hash digests also include PGP framing data. See https://www.rfc-editor.org/rfc/rfc4880#section-5.2.3:

"The concatenation of the data being signed and the signature data from the version number through the hashed subpacket data (inclusive) is hashed. The resulting hash value is what is signed."

This means you can't calculate a regular hash (like sha256) of a file on a client, and send that hash to a "PGP signing service" to receive an OpenPGP signature. There are two possible designs you could consider:

See https://openpgp.dev/book/signatures.html#creating-an-openpgp-signature-packet for a schematic outline of how OpenPGP signature packets work, and how the hash digest they contain is calculated.