Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Cryptography Fundamentals for Engineers

By Kokil Thapa | Last reviewed: September 2026

Cryptography fundamentals for engineers are not abstract math exercises. They are the concrete rules that keep passwords, payment callbacks, session cookies, and uploaded legal documents from leaking on a production Laravel or WordPress site. Most breaches I see in client audits trace back to basics: weak hashing, home-grown ciphers, keys stored in Git, or TLS misconfiguration—not exotic attacks. This guide maps security controls engineers actually ship to the primitives you need before touching REST API development or a client portal.

What Are Cryptography Fundamentals for Engineers?

Cryptography protects data in three states. Data at rest sits in MySQL or on disk. Data in transit crosses HTTPS, webhooks, and SMTP. Data in use lives in application memory during a request. Each state needs a different tool.

Engineers rarely implement algorithms from scratch. You choose primitives, wire them correctly, and manage keys. That discipline separates a secure booking portal from a breach waiting to happen.

Three Data StatesAt RestDB, files, backupsIn TransitHTTPS, webhooksIn UseRAM, sessionsAES-GCMDisk encryptionTLS 1.3Cert pinningShort TTLMinimal retentionKeys never live in source codeUse env vars, vaults, or KMS
Cryptography fundamentals for engineers start by matching controls to data at rest, in transit, and in use.

Core primitives you must recognise

  • Hashing — one-way digests (SHA-256, bcrypt, Argon2id). Used for passwords and integrity checks.
  • Symmetric encryption — one shared secret encrypts and decrypts (AES-256-GCM, ChaCha20-Poly1305).
  • Asymmetric encryption — key pairs for key exchange and small payloads (RSA, ECDH, Ed25519).
  • Digital signatures — prove authenticity without hiding content (Ed25519, ECDSA).
  • Key derivation — stretch passwords into keys safely (PBKDF2, scrypt, Argon2).

The NIST SP 800-57 key management guide remains the authoritative reference for key sizes and lifetimes. Bookmark it before you pick cipher suites for a new project.

How Do Cryptography Fundamentals for Engineers Handle Hashing vs Encryption?

Hashing and encryption solve different problems. Mixing them up is one of the most common mistakes on real client projects.

Hashing produces a fixed-length fingerprint. You cannot recover the original input. Password storage must use a slow, salted password hash—never SHA-256 alone. Encryption is reversible with the correct key. Use it when you must read the data later, such as encrypted passport numbers in a legal-tech portal.

GoalUseNever useExample
Store passwordsArgon2id or bcryptMD5, SHA-256 aloneLaravel Hash::make()
Verify file integritySHA-256 or SHA-512CRC32 for securityComposer package checksums
Encrypt database fieldsAES-256-GCMAES-ECB, home-grown XORLaravel encrypted casts
Sign webhooksHMAC-SHA256Plain SHA-256 of bodyStripe-style signatures
Exchange session keysECDH + AEADRSA PKCS#1 v1.5 paddingTLS 1.3 handshake

Password hashing in Laravel 13

Laravel 13 on PHP 8.3+ defaults to bcrypt. You can switch the driver to Argon2id when libsodium is available. The framework handles salting automatically.

/* config/hashing.php */
'driver' => env('HASH_DRIVER', 'argon2id'),

/* In a Form Request or service class */
use Illuminate\Support\Facades\Hash;

$hash = Hash::make($plainPassword);
Hash::check($plainPassword, $hash); /* constant-time compare */

Test generated hashes with the password generator tool for length and entropy—not for production secrets, but to validate policy rules before you enforce them in code.

Field-level encryption

When a column must be readable after storage, use authenticated encryption. AES-GCM appends an authentication tag that detects tampering. Laravel's encrypter wraps OpenSSL and expects a 32-byte key in APP_KEY.

use Illuminate\Support\Facades\Crypt;

$encrypted = Crypt::encryptString('PAN-123456789');
$plain = Crypt::decryptString($encrypted);

Rotating APP_KEY without a migration plan locks you out of existing ciphertext. Plan key versioning before you encrypt production rows. Cloud KMS patterns are covered in the GCP Cloud KMS fundamentals guide.

Hash or Encrypt?Need original data back?NoYesUse a hashPasswords, API key digestsUse AEADAES-GCM, ChaCha20Argon2id + unique saltRandom IV per messageNever encrypt passwords you only verify
Cryptography fundamentals for engineers: choose hashing when recovery is unnecessary, AEAD when it is.

Which Cryptography Fundamentals for Engineers Apply to Laravel and PHP 8.5?

PHP 8.5 ships with OpenSSL and sodium extensions enabled on most production hosts I manage. Laravel 13 builds on both. Symfony 8.1 projects follow the same rules with different facades.

Your job is configuration and boundary design—not low-level cipher code. Focus on these integration points.

Sessions identify users. Encrypt session payloads at rest when you store them in Redis 8.10 or a database. Mark cookies Secure, HttpOnly, and SameSite=Lax unless cross-site OAuth requires None.

/* config/session.php */
'encrypt' => true,
'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,
'same_site' => 'lax',

API tokens with Sanctum

Personal access tokens should be stored as hashes in the database. Laravel Sanctum shows only the plain token once at creation. That pattern mirrors how Stripe treats secret keys.

Pair token auth with rate limiting and HTTPS-only routes. Details overlap with GraphQL API design fundamentals, but the crypto layer stays identical: TLS outside, HMAC or signed JWTs at the edge when needed.

libsodium for greenfield crypto

When you are outside Laravel helpers, prefer sodium over composing raw OpenSSL calls. It is harder to misuse.

$key = sodium_crypto_secretbox_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
$ciphertext = sodium_crypto_secretbox($message, $nonce, $key);
$plain = sodium_crypto_secretbox_open($ciphertext, $nonce, $key);

The PHP sodium extension manual documents every constant. Read it before you touch nonce sizes or key lengths.

Request Crypto LayersBrowserTLS 1.3Cert verifyNginxTerminate SSLLaravelApp cryptoInside the applicationSession cookie (signed + encrypted)CSRF token (HMAC-based)Encrypted Eloquent attributesHashed password via Argon2idTLS alone does not encrypt database columns
Cryptography fundamentals for engineers span transport security and application-layer controls in Laravel stacks.

What Production Mistakes Break Cryptography Fundamentals for Engineers?

Theory is easy. Production breaks when shortcuts meet real traffic. These failures show up repeatedly on audits and incident calls.

  1. Hard-coded secrets in Git. API keys in .env.example, payment salts in controllers, old keys in commented blocks. Use environment variables and rotate on leak.
  2. Reused IVs or nonces. AES-GCM with a repeated nonce destroys confidentiality. Always generate a fresh random IV per encryption operation.
  3. Logging ciphertext or tokens. Debug logs during Khalti or eSewa callback debugging have exposed live secrets. Redact before write.
  4. Missing TLS on internal hops. Even server-to-server calls behind a VPC deserve HTTPS when credentials travel. See TCP/IP fundamentals for DevOps for network layering context.
  5. Trusting client-side crypto alone. JavaScript password hashing before POST does not replace server-side Argon2id. Attackers bypass the browser.

On legal-tech portals such as Mijar Law Associates, uploaded PDFs need access control plus encryption at rest on the filesystem or object store. Cryptography without authorisation still leaks files through IDOR bugs.

Webhook signature verification

Payment gateways sign callback bodies. Verify before you mark an order paid.

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $payload, $webhookSecret);

if (! hash_equals($expected, $signature)) {
    abort(401, 'Invalid signature');
}

Use hash_equals() for every secret comparison. Early returns on length mismatch defeat timing attacks. Encode test payloads with the Base64 encoder and decoder when you build fixture files—not for live secrets.

Certificate and TLS hygiene

Let's Encrypt on Ubuntu 24 with Certbot is standard on servers I administer. Auto-renew via cron. Disable TLS 1.0 and 1.1. Prefer TLS 1.3 cipher suites.

Apache or Nginx termination is documented in Linux system administration services. Misconfigured chain files cause mobile browser failures that look like application bugs.

Production Crypto FailuresSecrets in Git historyWeak password hashesReused nonces in GCMExpired TLS certsSkipped webhook HMACLogging bearer tokensFix: env secrets, vetted libs, auditsRotate keys, monitor cert expiry
Cryptography fundamentals for engineers fail in predictable ways—most are operational, not mathematical.

How Should Engineers Apply Cryptography Fundamentals for APIs and Payment Integrations?

Nepal-facing platforms often integrate eSewa, Khalti, IME Pay, and ConnectIPS alongside Stripe or PayPal. Each gateway documents its own signing scheme. The crypto pattern is the same: shared secret or public key, canonical payload, HMAC or RSA verify.

On a production Laravel eCommerce system, I treat payment callbacks as untrusted input until signature verification passes. Idempotency keys prevent duplicate captures when gateways retry webhooks.

Design checklist for REST APIs

  • Enforce HTTPS with HSTS on public endpoints.
  • Issue short-lived access tokens; rotate refresh tokens.
  • Store only hashed API keys; show plain text once at creation.
  • Sign outbound webhooks; document verification for integrators.
  • Encrypt PII columns that regulations or client contracts require.
  • Back up encrypted data and keys on separate paths.

Enterprise portals with document sharing—like those built under enterprise application development—need encryption plus audit logs. Crypto protects confidentiality; logs prove who accessed a file.

LDAP and directory auth introduce another layer. Read LDAP fundamentals alongside this page when Active Directory or FreeIPA handles identity and your app still encrypts data at rest.

Randomness and entropy

Never call rand() for security values. Use random_bytes() or random_int() in PHP. Laravel's Str::random() wraps secure generators.

$token = bin2hex(random_bytes(32)); /* 256-bit hex token */
$otp = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);

Validate JSON webhook fixtures with the JSON formatter before they enter your test suite. Broken encoding has caused signature mismatches that teams chased for hours.

The OWASP Cryptographic Storage Cheat Sheet aligns with every checklist above. Treat it as a pre-release gate for new features that touch secrets.

Key Takeaways

  • Hash passwords with Argon2id or bcrypt; never encrypt data you only need to verify.
  • Use AES-256-GCM or ChaCha20-Poly1305 for reversible field encryption, with a unique nonce every time.
  • Keep keys in environment variables or KMS—never in Git, never in client-side JavaScript alone.
  • Verify webhook and payment callbacks with HMAC or documented signatures before changing order state.
  • TLS 1.3 protects data in transit; it does not replace application-layer encryption for sensitive columns.
  • Audit logs and access control complete cryptography—ciphers alone do not stop authorised abuse.

People Also Ask

What is the difference between encoding and encryption?

Encoding transforms data for transport or storage—Base64, hex, URL encoding—and anyone can reverse it without a secret. Encryption requires a key and is designed to resist recovery without that key. Developers confuse the two because both produce unreadable strings. Use encoding for compatibility; use AEAD ciphers when confidentiality matters.

Should engineers build custom encryption algorithms?

No. Custom ciphers fail against modern analysis within hours. Production systems should call vetted libraries—OpenSSL, libsodium, Laravel Crypt—and follow published parameters. Your differentiation is key management and threat modelling, not a new block cipher.

How often should encryption keys be rotated?

Rotate when staff leave, after suspected compromise, or on a schedule your risk policy defines—often 90 to 365 days for data-encryption keys. TLS certificates typically renew every 90 days with Let's Encrypt. Plan dual-key periods so old ciphertext remains decryptable during migration.

Is HTTPS enough to secure an API?

HTTPS is necessary but not sufficient. It protects bytes on the wire. It does not validate business logic, prevent SQL injection, or encrypt database columns. Pair TLS with authentication, authorisation, input validation, and hashed or encrypted storage for secrets and PII.

Ship Cryptography You Can Maintain

Cryptography fundamentals for engineers boil down to picking the right primitive, using maintained libraries, and operating keys safely across deploys. Master hashing versus encryption, wire Laravel's built-ins correctly, verify every payment webhook, and treat TLS as the floor—not the ceiling. When you need a portal that handles documents, payments, and compliance together, review the Notary Nepal portfolio case or reach out via contact us to discuss custom software with proper crypto boundaries. Solid fundamentals today prevent emergency key rotations tomorrow.

Frequently Asked Questions

Hashing, symmetric and asymmetric encryption, digital signatures, and TLS transport—wired through vetted libraries like OpenSSL, libsodium, and Laravel's encrypter, never home-grown ciphers.

Hashing produces a one-way fingerprint you cannot reverse; use Argon2id or bcrypt for passwords and SHA-256 for integrity checks. Encryption is reversible with the correct key; use AES-256-GCM when you must read data later, such as encrypted passport numbers in a legal-tech portal. Mixing them up is one of the most common audit failures I see. Never store passwords with SHA-256 alone or encrypt data you only need to verify. Laravel's Hash facade handles password hashing; Crypt handles authenticated field encryption with APP_KEY.

Encoding (Base64, hex, URL encoding) transforms data for transport and anyone can reverse it without a secret. Encryption requires a key and resists recovery without that key.

No. Custom ciphers fail modern analysis quickly. Use OpenSSL, libsodium, or Laravel Crypt with published parameters; focus on key management instead.

Rotate when staff leave, after suspected compromise, or on a schedule your risk policy defines—often 90 to 365 days for data-encryption keys. TLS certificates typically renew every 90 days with Let's Encrypt on Ubuntu 24 via Certbot. Plan dual-key periods before rotating Laravel APP_KEY so old ciphertext remains decryptable during migration; rotating without a migration plan locks you out of encrypted database rows. NIST SP 800-57 remains the authoritative reference for key sizes and lifetimes when you define rotation policy for production portals.

HTTPS is necessary but not sufficient. TLS 1.3 protects bytes in transit between client and server, yet it does not validate business logic, stop SQL injection, or encrypt sensitive columns sitting in MySQL. Pair TLS with HSTS on public endpoints, authentication, authorisation, input validation, and hashed or encrypted storage for secrets and PII. On payment integrations, treat callback bodies as untrusted until HMAC or documented signature verification passes. Application-layer controls matter even when every hop uses HTTPS, including server-to-server calls behind a VPC.

Laravel 13 on PHP 8.3 or higher defaults to bcrypt, which handles salting automatically. Switch the driver to Argon2id in config/hashing.php when libsodium is available on the host—most production PHP 8.5 servers I manage ship both OpenSSL and sodium extensions enabled. Use Hash::make() and Hash::check(), which performs constant-time comparison. Never use MD5, SHA-256 alone, or client-side JavaScript hashing as a substitute; attackers bypass the browser. Test password policy rules with a generator tool for length and entropy before enforcing them in Form Requests.

Use authenticated encryption when a database column must be readable after storage—encrypted PAN numbers, passport details, or similar PII in client portals. Laravel's Crypt facade wraps OpenSSL AES-GCM and appends an authentication tag that detects tampering. Call Crypt::encryptString() and Crypt::decryptString() with a 32-byte APP_KEY from environment variables, never from Git. Generate a fresh random nonce for every encryption operation; reusing a nonce with AES-GCM destroys confidentiality. Plan key versioning before encrypting production rows because blind APP_KEY rotation without migration locks you out of existing ciphertext.

Treat every gateway callback as untrusted input until signature verification passes. Read the raw body with file_get_contents on php://input, fetch the header signature, and compute hash_hmac with sha256 using your shared webhook secret. Compare with hash_equals() to defeat timing attacks—never use a plain equals operator. Abort with 401 on mismatch before updating order state. Nepal-facing platforms integrating eSewa, Khalti, IME Pay, or ConnectIPS follow the same pattern as Stripe: canonical payload, documented signing scheme, verify first. Redact tokens from debug logs; I have seen live secrets exposed during callback troubleshooting.

Hard-coded secrets in Git, API keys left in .env.example, and old keys in commented controller blocks top every audit I run. Reused IVs or nonces with AES-GCM leak plaintext. Debug logs during payment callback testing expose live tokens. Missing TLS on internal server-to-server hops sends credentials in cleartext. Trusting client-side crypto alone leaves passwords exposed to direct POST attacks. Cryptography without authorisation still leaks files through IDOR bugs—uploaded PDFs on legal-tech portals need access control plus encryption at rest. Most failures are operational shortcuts, not broken math.

Store personal access tokens as hashes in the database, mirroring how Stripe treats secret keys—the plain token is shown only once at creation. Pair token auth with rate limiting and HTTPS-only routes. Never log plaintext tokens during debugging. The crypto layer for REST APIs stays consistent whether you use Sanctum, signed JWTs, or HMAC at the edge: TLS outside the application, hashed secrets inside the database, short-lived access tokens with rotated refresh tokens where your API design requires them. Issue tokens over HTTPS and enforce HSTS on public endpoints.

Enable session encryption when storing payloads in Redis 8.10 or a database by setting encrypt to true in config/session.php. Mark cookies Secure, HttpOnly, and SameSite=Lax unless cross-site OAuth requires None. Set secure from SESSION_SECURE_COOKIE in production so session identifiers never travel over cleartext HTTP. Session crypto protects data at rest in the session store; it complements but does not replace TLS for data in transit. Symfony 8.1 projects follow the same boundary rules with different facades—configuration and threat modelling matter more than writing low-level cipher code.

Prefer libsodium for greenfield crypto outside Laravel helpers because it is harder to misuse than composing raw OpenSSL calls. Generate keys with sodium_crypto_secretbox_keygen(), use random_bytes for nonce sizes matching SODIUM_CRYPTO_SECRETBOX_NONCEBYTES, and decrypt with sodium_crypto_secretbox_open. Read the PHP sodium extension manual before touching nonce sizes or key lengths—wrong constants cause silent failures or weak encryption. PHP 8.5 ships the sodium extension enabled on most production hosts I administer. Laravel's built-in Crypt and Hash facades cover most application needs; reach for sodium when you need lower-level control with safer defaults.

Use Let's Encrypt on Ubuntu 24 with Certbot and auto-renew via cron—the standard on servers I administer. Disable TLS 1.0 and 1.1; prefer TLS 1.3 cipher suites on Apache or Nginx termination. Misconfigured certificate chain files cause mobile browser failures that look like application bugs, so verify the full chain after every renewal. TLS protects data in transit across HTTPS, webhooks, and SMTP, but it does not replace application-layer encryption for sensitive database columns or hashed token storage. Cryptography fundamentals treat transport security as the floor, not the ceiling.

Never call rand() for security values. Use random_bytes() or random_int() in PHP; Laravel's Str::random() wraps secure generators. For a 256-bit hex token, bin2hex(random_bytes(32)) is appropriate. Generate OTPs with random_int padded to six digits. Validate JSON webhook test fixtures with a JSON formatter before they enter your test suite—broken encoding has caused signature mismatches teams chased for hours. Entropy quality matters for session keys, idempotency keys on payment retries, and one-time API secrets shown at Sanctum token creation.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: