3

In reading about asymmetric encryption a while ago, I remember reading that you could "decrypt" an unencrypted file with your private key, then others (anyone) could "encrypt" it with your public key to both recover the original file and be sure it was from you. Obviously, the proper way to do this is by signing, which GPG handles. However… Is this possible with GPG?

I’m trying the following command.

gpg --output decrypted.jpg --decrypt --local-user my-email-address original.jpg

It doesn’t output any remarks or errors, but no decrypted.jpg is created.

Benoit Esnard
  • 13,979
  • 7
  • 65
  • 65
lukejanicke
  • 325
  • 2
  • 7
  • If the input is no valid OpenPGP message, GnuPG fails with an error message. Try investigating the file with `pgpdump` or `gpg --list-packets`. Are you running the very specific command, or do you have any further redirects applied (ie. discarding STDERR)? – Jens Erat Aug 20 '16 at 18:18
  • 1
    "decrypt an unencrypted file".. this is just nonsense. do you have a source on this? – cremefraiche Aug 20 '16 at 19:57
  • Have you tried *encrypting* with your private key? That's the correct use... – Ben Aug 20 '16 at 20:50
  • 1
    @Ben You can't encrypt with a private key. (With *some* algorithms you can carry out the encryption primitive with the private/public keys swapped, but not all of them, and even when it's mathematically possible, it's pointless.) Don't confuse encryption with signing. Signing is not encryption with a private key. Read tim's answer. – Gilles 'SO- stop being evil' Aug 20 '16 at 21:32
  • My mistake. I had the misunderstanding that signing *was* encrypting a digest of of a message using the private key. I didn't remember it's actually a decryption operation. Very informative answer! Although now I'm curious: without the public key, can this operation be reversed? So wouldn't that be a (useless, since the key is known) form of encryption in some sense? I know it's irrelevant to the specific question... – Ben Aug 20 '16 at 21:46

2 Answers2

10

Difference between signing and decrypting

I think your confusion stems from the fact that signing is in theory indeed somewhat similar to decryption for some algorithms (for example RSA).

Wikipedia for example phrases it like this:

Suppose Alice wishes to send a signed message to Bob. She can use her own private key to do so. She produces a hash value of the message, raises it to the power of d (modulo n) (as she does when decrypting a message), and attaches it as a "signature" to the message.

This is however not how it is done in practice, and it is why your approach doesn't work.

For a more in-depth explanation of signing and decryption see eg here:

In the abstract world of textbooks, RSA signing and RSA decryption do turn out to be the same thing. In the real world of implementations, they are not. So don't ever use a real-world implementation of RSA decryption to compute RSA signatures. In the best case, your implementation will break in a way that you notice. In the worst case, you will introduce a vulnerability that an attacker could exploit.

Furthermore, don't make the mistake of generalizing from RSA to conclude that any encryption scheme can be adapted as a digital signature algorithm. That kind of adaptation works for RSA and El Gamal, but not in general.

Regarding PGP, it doesn't sign the message itself, but instead it signs a hash digest of the message:

PGP uses a cryptographically strong hash function on the plaintext the user is signing. This generates a fixed-length data item known as a message digest. (Again, any change to the information results in a totally different digest.)

Then PGP uses the digest and the private key to create the "signature." PGP transmits the signature and the plaintext together. Upon receipt of the message, the recipient uses PGP to recompute the digest, thus verifying the signature. PGP can encrypt the plaintext or not; signing plaintext is useful if some of the recipients are not interested in or capable of verifying the signature.

Here is an image describing the process:

enter image description here

Why you can't just decrypt a message to sign it

The above is all well and good, and we know that we shouldn't decrypt messages to sign them in practice, but why can't we do it just for fun?

Because that's not how PGP or GPG work. A full explanation of the inner workings would probably be too much for this question, but see for example How does GPG verify succesful decryption?.

In short, PGP doesn't just do some mod operation on the data on decryption, the .pgp format is well defined and contains various information. Note also that PGP doesn't actually use asymmetric encryption such as RSA on the message itself, but on a key which is then used to symmetrically encrypt the message.

Conclusion

To summarize, if you were to use plain RSA, you could use decryption to sign a message (but you shouldn't), but PGP and GPG aren't plain RSA, so you can't just decrypt a message to sign it.

tim
  • 29,122
  • 7
  • 96
  • 120
  • "… but why can't we do it just for fun? Because that's not how PGP or GPG work." That thoroughly answers my question. Plus the bit about GPG not being plain RSA. – lukejanicke Aug 22 '16 at 11:08
  • Doesen't he need to decrypt the signature in order to verify that it does match the digest? – Ini Jan 10 '19 at 23:40
1

You seem to recall the basics of how digital signatures work in the case of textbook RSA (that is RSA slightly oversimplified).

The RSA public key is composed of N (the modulus) which is the product of two large prime numbers (e.g., in 2048-bit RSA, N is a 2048-bit product of two 1024-bit primes) and the public exponent, e which is usually set to be 65537. The private key similarly consists of N and d, the private exponent.

(If you know the prime numbers p and q, you can quickly calculate the private exponent, d, via Euclid's extended algorithm, where d is chosen to guarantee that (m^e)^d mod N = m by finding d = e^-1 mod (p-1)(q-1) which works due to Euler's theorem. In general, there is no publicly known way of finding d given N and e that is asymptotically more efficient than factoring N.)

Textbook RSA encryption let's anyone with your public key take a message m (which is assumed to be encoded into an integer that is smaller than N) and make a ciphertext c by calculating c = m^e mod N (modular exponentiation), which can only be deciphered by people possessing the private key. Textbook RSA decryption is the same procedure of modular exponentiation, except instead of acting on the message and using the public exponent, it acts on the ciphertext with the private exponent. That is if you have the private key and the ciphertext, you can calculate m via m = c^d mod N.

Signatures in textbook RSA are sometimes called "encrypting with the private key" and works very similarly with the main difference being the order. The person signing the message at the start uses modular exponentiation with the private key (similar to RSA decryption) to create a signature S = m^d mod N. Then when you give someone a signed message (that is m and S together), they can verify the message wasn't tampered with by doing modular exponentiation on the signature with the public key and verifying that S^e mod N is equal to the original message.

The main difference between textbook RSA and real RSA for encryption, is that in real RSA you do not use RSA to encrypt the message you intend to send. Instead, you create a random symmetric key (e.g., a 128-bit AES key), and use that random symmetric key to encrypt your arbitrarily sized message (which may be much larger than 2048 bits which is roughly the size of N), and then use textbook RSA to encrypt this random symmetric key. That is you pass the ciphertext c_aes = AES(k, m) (which will be as many blocks as the plaintext message) and the RSA-encrypted AES key c_key = k^e mod N to someone when you want to send an encrypted message. They then decrypt the AES key with their RSA private key, and use the decrypted key to decrypt c_aes.

Similarly, the main difference between textbook RSA and real RSA for signing, is that in real RSA, you do not perform modular exponentiation on the message, which could be much larger than the modulus N. Instead, you run a cryptographic hash function on the message (like SHA-256), and then create a signature on this hash value. That is to sign you first hash the message h = sha256(m), then generate the signature S = h^d mod N. To verify, someone with your public key, signature, and plaintext message can check that S^e mod N is equal to their computation of the hash value of the associated plaintext message.

dr jimbob
  • 38,936
  • 8
  • 92
  • 162