Skip to content

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:

  1. Client encrypts request with server’s public key
  2. Server decrypts with private key
  3. 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 security gaps
┌─────────────────────────────────────────────────────────────┐
│ 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
┌─────────────────────────────────────┐
│ CIA Security Triad │
├─────────────────────────────────────┤
│ C - Confidentiality (Encryption) │
│ I - Integrity (Signatures) │
│ A - Authenticity (Signatures) │
└─────────────────────────────────────┘

How Encryption Works (Confidentiality)

Encryption flow
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)

Digital signature flow
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:

OperationKey Used to CreateKey Used to Verify/Open
EncryptionRecipient’s PUBLIC keyRecipient’s PRIVATE key
SignatureSender’s PRIVATE keySender’s PUBLIC key

It’s not about “swapping” keys. These are different cryptographic operations.

Python Example: The Difference

encryption_vs_signature.py
# ENCRYPTION - Confidentiality
# ========================================
# Use recipient's public key to encrypt
message = "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 sign
message = "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 altered

Combined Approach: Sign Then Encrypt

For complete security, you need both:

secure_send.py
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:

ecdsa_demo.py
from cryptography.hazmat.primitives.asymmetric import ec
from 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()
# Signing
message = b"Message to sign"
signature = private_key.sign(message, hashes.SHA256())
# Verifying
public_key.verify(signature, message, hashes.SHA256())
# There is NO encrypt() operation in ECDSA
# Signatures are mathematically different from encryption

The reason

I think the confusion comes from three sources:

  1. RSA does both: RSA can encrypt and sign with the same keys, which makes people think they’re the same operation
  2. Oversimplified tutorials: Many tutorials say “signing is encrypting the hash with the private key” because it’s easier to explain
  3. 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:

ScenarioWhat You NeedWhy
Send secret to recipientEncryptionOnly recipient can read
Prove you sent somethingSignatureVerifiable identity
Secure communicationBothConfidentiality + authenticity
Publish software updateSignature onlyNo 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:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments