What's the Difference Between Encryption and Digital Signatures?
Problem
When I first learned about public key cryptography, I was confused about one thing: if I have a public key and a private key, why do I need both encryption AND digital signatures? Aren’t they just the same thing with keys swapped?
I thought signing a message was just “encrypting with the private key instead of the public key.” That misconception led me to build insecure systems.
Here’s the problem: encryption and digital signatures are fundamentally different operations serving different security goals.
What happened?
I was designing an API authentication system. My plan was simple:
- Client encrypts request with server’s public key
- Server decrypts with private key
- Server processes the request
I assumed that since only the server could decrypt the message, the server would know it came from me. I was wrong.
Here’s why my assumption failed:
┌─────────────────────────────────────────────────────────────┐│ ENCRYPTION ONLY │├─────────────────────────────────────────────────────────────┤│ Sender encrypts with recipient's PUBLIC key ││ → Only recipient can decrypt with PRIVATE key ││ → Confidentiality: YES ││ → But WHO sent it? Anyone with the public key! ││ → Was it tampered? Can't tell! │└─────────────────────────────────────────────────────────────┘Anyone who has the server’s public key (which is usually public) could send an encrypted message. Encryption proves nothing about who sent it.
The solution
The solution is understanding that encryption and signatures address different parts of the CIA triad:
┌─────────────────────────────────────┐ │ CIA Security Triad │ ├─────────────────────────────────────┤ │ C - Confidentiality (Encryption) │ │ I - Integrity (Signatures) │ │ A - Authenticity (Signatures) │ └─────────────────────────────────────┘How Encryption Works (Confidentiality)
SENDER RECEIVER │ │ │ Has: Receiver's PUBLIC key │ Has: Receiver's PRIVATE key │ │ │ ┌────────────────────────┐ │ │ │ Encrypt message with │ │ │ │ RECEIVER's public key │ │ │ └──────────┬─────────────┘ │ │ │ │ │ │ Encrypted msg │ │ │───────────────────►│ │ │ │ │ │ ┌──────────────┤ │ │ │ Decrypt with │ │ │ │ PRIVATE key │ │ │ └──────────────┤ │ │ │ │ │ Security: │ │ │ ✓ Only receiver │ │ │ can read │ │ │ ✗ Anyone could │ │ │ have sent it │How Digital Signatures Work (Integrity + Authenticity)
SENDER RECEIVER │ │ │ Has: Sender's PRIVATE key │ Has: Sender's PUBLIC key │ │ │ ┌────────────────────────┐ │ │ │ Sign message hash │ │ │ │ with PRIVATE key │ │ │ └──────────┬─────────────┘ │ │ │ │ │ │ Message + │ │ │ Signature │ │ │───────────────────►│ │ │ │ │ │ ┌──────────────┤ │ │ │ Verify with │ │ │ │ PUBLIC key │ │ │ └──────────────┤ │ │ │ │ │ Security: │ │ │ ✓ Proves sender │ │ │ ✓ Not tampered │ │ │ ✗ Message is │ │ │ visible to all │The Key Difference: Whose Keys?
This is where I got confused. The key insight:
| Operation | Key Used to Create | Key Used to Verify/Open |
|---|---|---|
| Encryption | Recipient’s PUBLIC key | Recipient’s PRIVATE key |
| Signature | Sender’s PRIVATE key | Sender’s PUBLIC key |
It’s not about “swapping” keys. These are different cryptographic operations.
Python Example: The Difference
# ENCRYPTION - Confidentiality# ========================================# Use recipient's public key to encryptmessage = "Secret message"recipient_public_key = load_public_key(recipient)
encrypted = encrypt(message, recipient_public_key)# Only recipient can decrypt with their private key# But ANYONE could have created this encrypted message
# SIGNING - Integrity & Authentication# ========================================# Use sender's private key to signmessage = "Important message"sender_private_key = load_private_key(sender)
signature = sign(hash(message), sender_private_key)# Anyone can verify with sender's public key# Proves the message came from this specific sender# Proves the message wasn't alteredCombined Approach: Sign Then Encrypt
For complete security, you need both:
def secure_send(message, sender_private_key, recipient_public_key): # Step 1: Sign for integrity and authenticity signature = sign(hash(message), sender_private_key)
# Step 2: Package message with signature signed_package = { 'message': message, 'signature': signature }
# Step 3: Encrypt for confidentiality encrypted_package = encrypt(signed_package, recipient_public_key)
return encrypted_package
def secure_receive(encrypted_package, recipient_private_key, sender_public_key): # Step 1: Decrypt signed_package = decrypt(encrypted_package, recipient_private_key)
# Step 2: Verify signature is_valid = verify( hash(signed_package['message']), signed_package['signature'], sender_public_key )
if is_valid: return signed_package['message'] else: raise SecurityError("Signature verification failed")Why “Sign = Encrypt with Private Key” Is Wrong
This oversimplification only works for RSA. For ECDSA and other signature algorithms, there’s no encryption involved at all:
from cryptography.hazmat.primitives.asymmetric import ecfrom cryptography.hazmat.primitives import hashes
# ECDSA signature algorithm# Note: ECDSA has NO encryption capability# This proves signatures are NOT "encrypting with private key"
private_key = ec.generate_private_key(ec.SECP256R1())public_key = private_key.public_key()
# Signingmessage = b"Message to sign"signature = private_key.sign(message, hashes.SHA256())
# Verifyingpublic_key.verify(signature, message, hashes.SHA256())
# There is NO encrypt() operation in ECDSA# Signatures are mathematically different from encryptionThe reason
I think the confusion comes from three sources:
- RSA does both: RSA can encrypt and sign with the same keys, which makes people think they’re the same operation
- Oversimplified tutorials: Many tutorials say “signing is encrypting the hash with the private key” because it’s easier to explain
- Same key terminology: Both use “public key” and “private key,” but the roles are completely different
The key insight is that these are separate tools for separate jobs:
| Scenario | What You Need | Why |
|---|---|---|
| Send secret to recipient | Encryption | Only recipient can read |
| Prove you sent something | Signature | Verifiable identity |
| Secure communication | Both | Confidentiality + authenticity |
| Publish software update | Signature only | No need to hide code, just prove it’s yours |
Summary
In this post, I explained the fundamental difference between encryption and digital signatures. The key point is that encryption provides confidentiality (only the intended recipient can read) while signatures provide integrity and authenticity (proving who sent it and that it wasn’t altered). When you need all three security properties, use both: sign first, then encrypt.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Reddit Discussion: Encryption vs Digital Signatures
- 👨💻 RFC 5480 - Elliptic Curve Cryptography
- 👨💻 NIST Cryptographic Standards
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments