this post was submitted on 11 Apr 2025
217 points (95.8% liked)
Programmer Humor
22324 readers
2160 users here now
Welcome to Programmer Humor!
This is a place where you can post jokes, memes, humor, etc. related to programming!
For sharing awful code theres also Programming Horror.
Rules
- Keep content in english
- No advertisements
- Posts must be related to programming or programmer topics
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
Public is used to encrypt, private is used to decrypt.
But why? Public is public. People can take my public key. The can encrypt my commit, making it indistinguishable from my commit.
Isn't the idea to use your private key for encryption so that everyone can use your public key to decrypt your signature and to verify that it's you who actually did the commit, because no one else has access to the private key?
Consider a key pair, consisting of two brutally large numbers, but otherwise pretty much identical. Magical math exists that makes it so that if you math your data with one of these brutally large numbers, you get the original data back only if you math it with the other large number. That's basically it.
Now we slap convention onto this, and keep one of the paired, large numbers a secret, and call it our private key, the other number is disseminated and called the public key for that reason.
Now everyone can math data with your public key, so that only the paired private key, which only you know, can de-math it. This is encryption/decryption.
Signing is very similar, but now you use your private key, which only you know, to math a digest of your data, and all the world can de-math this correctly only with your public key, thus proving it was indeed your private key used to math the data in the first place, and by extension attribute the signature to your public key identity. Your private key is never known to anyone but you, which is an essential difference to "classical" symmetric encryption with a shared secret.
You may realize how easily a code signature can become a liability, if you fail to keep your private key secret for any reason. You can be trivially impersonated, with basically no chance of recourse or deniability with an SSH key, while you can at least invalidate a GPG key publicly and mark it as "stolen" that way. This is potentially very important, if there's any legal meaning attached to your signature, and if not, why bother with code signing in the first place, if "trust me bro" is well enough.
Yeah, sorry, I meant signing, not encrypting. I know about asymmetrical encryption. That's why I was confused by the original statement. For signing you use your private key so that others can verify your identity by using your public key for checking the signature. For encrypting data you use the public key of the receiver.
~~The original comment used the public key for signing, which is not what you want to do.~~ I now read the explanation.
Did you reply to the correct comment?
And they can also encrypt things with it. That's the whole point. Only the owner of the private key can decrypt what's been encrypted with the public key, and that establishes ownership.
Why the person you responded to is being down-voted, and why people in this thread don't seem to understand how shared keys work is pretty insane to me. This technology has exited, and remained relatively unchanged, for like... 40 years.
That's not how commits are verified. The commit is signed with your private key (not encrypted), not your public key. Referencing the public key simply tells the ssh agent which key-pair to use, and the ssh daemon decides which key to use (public or private) based on the action that you're doing.
Signing a commit requires your private key, so no. People can't just grab your public key and sign commits to impersonate you. They can simply encrypt text with it. That's it. This is all self evident by the git property
user.signingkey
"sign". You're signing the commit message, not encrypting anything.Sorry for the confusion about "encryption". I meant "signing" which is encrypting a hash of the commit with your private key, so that others can verify that your the author of the commit using your public key and the hash.
I think, the only confusion here was the original comment that referenced the public key for signing, but this was resolved, as it is just telling git which key pair to use. Probably, all people here understand the basics of asymmetrical encryption and signing and it was merely misunderstanding of how the command for signing git commits can be used.
Signing isn't encryption. It's a non-cipher hash.
Which outputs the hash of the signed statement, which was signed with my private key;
And can then be verified using my public key;
Mathematically, signing is encryption using the private key. That's how the algorithm works. The input to the function is irrelevant.
Mathematically, they're not even close to the same. How you could ever assert such an indefensibly and empirically incorrect statement is beyond my reasoning skills to understand.
PKC Key signing uses hashing algorithms like RSA, ElGamal, DSA, and ECDSA to create one way cryptographic hashes for given input data. The singular purpose of these signatures is to verify the integrity of data. Not to protect the data in any way whatsoever or to be reversed into clear text; again, the hash is one way.
PKC encryption uses encryption algorithms like AES, Blowfish, Twofish, PGP, and Diffie-Hellman to create reversible cipher text. The difference being, the cipher text of an encryption process can be reversed and represents the data itself.
All of this is clearly outlined in the RFC: https://www.ietf.org/rfc/rfc4880.txt
I know it because I've actually implemented RSA as an exercise and know how it works.
What you're talking about with hashes is an implementation detail. It's an important one, because using exactly the same algorithm for signing and encryption has some security pitfalls, and it will usually be slower. However, the function you call is exactly the same. The hash is encrypted with the private key. It can be verified by generating the same hash, decrypting with the public key, and matching the two hashes.
See also: https://cryptobook.nakov.com/digital-signatures/rsa-signatures
The operation "h^d^ (mod n)" is just RSA encryption, but with the private key.
Thanks for that rabbit hole. My former colleagues and I have just started a new conversation thread in our WhatsApp group about the differences of (non-) cryptographic hashes and encryption. And all because I was confused why you've chosen to reference the public key file in your original comment. Well, at least I'm learning something.
I think encrypting with a public key is mostly used in client -> server traffic (client encrypts with server's public key, server decrypts with private), and not code signing. However, I'm no TLS/asymmetric crypto savant.
Encryption can only be done with the PGP public key. Even if you specifically use the private key, it contains the public key, and GPG already knows to use the public key for encryption. You cannot create encrypted cipher text using a GPG private key.
Likewise, you cannot decrypt data using the public key, nor can you sign statements with a public key. For those processes you must use a private key.
I had no idea people found GPG this confusing...
I don't have much experience in the realm of gpg. My experience is mostly with TLS. From what I know, if you're doing client authentication, you encrypt your message with your private key, and then the public key on a cert is used for validating that the message actually came from you.
I think code signing is similar to client auth, but not positive. Again, I use TLS, but I'm not a professional
https://about.signpath.io/code-signing/theory#%3A%7E%3Atext=Software+publishers+use+a+secret%2Cpart+of+the+distribution+package.
Edit:
What I found from Wikipedia:
The client sends a CertificateVerify message, which is a signature over the previous handshake messages using the client's certificate's private key. This signature can be verified by using the client's certificate's public key. This lets the server know that the client has access to the private key of the certificate and thus owns the certificate.
https://en.m.wikipedia.org/wiki/Transport_Layer_Security#Client-authenticated_TLS_handshake
This is TLS authentication via SSH, which is a completely different ballgame than using SSH keys for data encryption, decryption, and verification.