Skip to content
Cryptography Basics Explained — Symmetric vs Asymmetric, Hashing & Signatures

Cryptography Basics Explained — Symmetric vs Asymmetric, Hashing & Signatures

DodaTech Updated Jun 15, 2026 6 min read

Cryptography is the practice of securing communication by transforming data into unreadable formats that only authorized parties can reverse.

What You’ll Learn

In this tutorial, you’ll learn the difference between symmetric and asymmetric encryption, how hash functions work, digital signatures, and how certificates establish trust — with Python examples using the cryptography library.

Why It Matters

Every time you visit an HTTPS website, send an email, or use a password manager, cryptography is protecting your data. Without it, all online communication would be readable by anyone.

Real-World Use

When you visit a bank’s website, TLS uses asymmetric encryption to exchange a session key, then symmetric encryption (AES) to encrypt all data. Your browser verifies the bank’s certificate against trusted CAs. Durga Antivirus Pro uses cryptographic hashes to verify file integrity and detect malware signatures.


graph TD
  subgraph "Encryption Types"
    A[Symmetric] --> B[Same Key Encrypt/Decrypt]
    C[Asymmetric] --> D[Public Key Encrypt]
    C --> E[Private Key Decrypt]
  end
  subgraph "Hash Functions"
    F[SHA-256] --> G[Fixed 256-bit Output]
    H[bcrypt] --> I[Password Hashing + Salt]
  end
  subgraph "Digital Signatures"
    J[Sign with Private Key]
    K[Verify with Public Key]
  end

Symmetric Encryption

Uses the same key for encryption and decryption. Fast and efficient for bulk data.

AlgorithmKey SizeStatus
AES-256256 bitsSecure (industry standard)
ChaCha20256 bitsSecure (modern alternative)
DES56 bitsBroken (brute-forced in < 1 day)
3DES168 bitsDeprecated (slow, vulnerable)

Asymmetric Encryption

Uses a key pair: public key (encrypt, share freely) and private key (decrypt, keep secret). Slower than symmetric, used for key exchange and digital signatures.

AlgorithmKey SizeUse
RSA2048-4096 bitsKey exchange, signatures
ECDSA256-521 bitsSignatures (smaller keys)
X25519256 bitsKey exchange (fast, secure)

Encrypting and Decrypting with Python

from cryptography.fernet import Fernet

# Generate a symmetric key
key = Fernet.generate_key()
cipher = Fernet(key)

print(f"Key: {key.decode()}")

# Encrypt a message
message = b"Sensitive data: credit card number 1234-5678-9012-3456"
encrypted = cipher.encrypt(message)
print(f"Encrypted: {encrypted}")

# Decrypt the message
decrypted = cipher.decrypt(encrypted)
print(f"Decrypted: {decrypted.decode()}")

Expected output:

Key: gAAAAAB... (random base64-encoded key)
Encrypted: gAAAAAB... (ciphertext, different each time)
Decrypted: Sensitive data: credit card number 1234-5678-9012-3456

RSA Asymmetric Encryption

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

# Generate RSA key pair (private key contains both keys)
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
)
public_key = private_key.public_key()

# Encrypt with public key
message = b"Secret message for the recipient"
ciphertext = public_key.encrypt(
    message,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None,
    ),
)
print(f"Ciphertext (hex): {ciphertext.hex()[:40]}...")

# Decrypt with private key
plaintext = private_key.decrypt(
    ciphertext,
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None,
    ),
)
print(f"Decrypted: {plaintext.decode()}")

Expected output:

Ciphertext (hex): a1b2c3d4e5... (2048-bit encrypted output)
Decrypted: Secret message for the recipient

Hashing with SHA-256

from cryptography.hazmat.primitives import hashes

def hash_data(data: bytes) -> str:
    digest = hashes.Hash(hashes.SHA256())
    digest.update(data)
    return digest.finalize().hex()

print(f"SHA-256 of 'hello': {hash_data(b'hello')}")
print(f"SHA-256 of 'Hello': {hash_data(b'Hello')}")
print(f"SHA-256 of 'hello!': {hash_data(b'hello!')}")
print()
print(f"Length: {len(hash_data(b'hello'))} hex chars = {len(hash_data(b'hello')) * 4} bits")

Expected output:

SHA-256 of 'hello': 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
SHA-256 of 'Hello': 185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
SHA-256 of 'hello!': ce06092fb94d9ff8d9c5f307ba414db87cab078a85e2d3a2b3e0f8b9b40bb302

Length: 64 hex chars = 256 bits

Notice how a single character change produces a completely different hash — this is the avalanche effect.

Digital Signatures

A digital signature proves the authenticity and integrity of a message. The sender signs with their private key; anyone can verify with the corresponding public key.

from cryptography.hazmat.primitives.asymmetric import padding

# Sign with private key
message = b"Transfer $1000 to account 12345"
signature = private_key.sign(
    message,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH,
    ),
    hashes.SHA256(),
)
print(f"Signature: {signature.hex()[:40]}...")

# Verify with public key
try:
    public_key.verify(
        signature,
        message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH,
        ),
        hashes.SHA256(),
    )
    print("Signature VALID: Message is authentic")
except Exception:
    print("Signature INVALID: Message was tampered!")

Expected output:

Signature: 8f3a2b1c... (256-byte signature)
Signature VALID: Message is authentic

Certificates and PKI

A digital certificate binds a public key to an identity (domain name, organization). Certificate Authorities (CAs) sign certificates, creating a chain of trust. When you visit an HTTPS site, your browser checks:

  1. The certificate is signed by a trusted CA
  2. The domain name matches
  3. The certificate hasn’t expired
  4. It hasn’t been revoked (via CRL or OCSP)

Hash Functions vs Encryption

HashEncryption
Reversible?No (one-way)Yes (with key)
Output lengthFixed (256 bits for SHA-256)Same as input length
Key?NoYes
PurposeIntegrity, passwordsConfidentiality

Common Mistakes

  1. Rolling your own cryptography: Use battle-tested libraries. Home-grown crypto always has flaws.
  2. Storing passwords with SHA-256 instead of bcrypt/argon2: SHA-256 is fast — attackers can try billions of passwords per second. Use slow, salted password hashes.
  3. Using ECB mode for AES: ECB encrypts each block independently, revealing patterns. Use CBC or GCM.
  4. Hardcoding encryption keys: Keys should be stored in secure vaults, environment variables, or HSM — never in source code.
  5. Ignoring key rotation: Using the same key for years increases exposure. Rotate keys regularly.

Practice Questions

  1. What is the difference between symmetric and asymmetric encryption? Symmetric uses one key for both operations (fast). Asymmetric uses a key pair (public/private, slower but enables key exchange).

  2. What property makes hash functions suitable for password storage? They’re one-way (can’t reverse to find the original password) and deterministic (same input always produces same hash).

  3. How does a digital signature prove authenticity? Only the private key holder can create a valid signature. Anyone with the public key can verify it.

  4. What is a certificate authority? A trusted third party that issues digital certificates, binding public keys to identities.

  5. Why should you never use ECB mode encryption? ECB encrypts each block independently, so identical plaintext blocks produce identical ciphertext blocks — leaking patterns.

Challenge

Implement a secure chat protocol: one user encrypts a message with the recipient’s public key (RSA) and signs it with their own private key. The recipient decrypts and verifies the signature.

Real-World Task

Click the padlock icon in your browser’s address bar. View the certificate for this page. Which CA issued it? What encryption algorithm does it use? When does it expire?

Mini Project: File Encryption Tool

Build a command-line tool that encrypts/decrypts files using AES-256-GCM. Support password-based key derivation (PBKDF2). Include integrity verification.

Security angle: Understanding cryptography is essential for building secure software. Doda Browser uses the same encryption principles to protect your saved passwords and browsing data.

What’s Next

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

What’s Next

Congratulations on completing this Cryptography Basics tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro