---
name: harden-crypto-implementations
description: "Defensive methodology against exploitation of broken application cryptography: CBC padding oracles, AES-GCM and stream-cipher nonce/IV reuse, and weak-primitive misuse (ECB, DES/3DES, RC4, MD5/SHA-1, RSA PKCS#1 v1.5, static IVs) that let an attacker decrypt, forge, or tamper with protected data (MITRE ATT&CK T1557, T1600, T1040). Signals live in web and application error logs, crypto-library exceptions, WAF and reverse-proxy logs, and Zeek ssl.log; much exposure shows only in code and TLS config. Gives the defender view of each flaw class, the errors to log and alert on, a hunt across logs and source, and primitive-level hardening mapped to public standards and, where they ground, UMBRASEC guide controls. Use when hardening or reviewing an encryption implementation, triaging a burst of padding or decryption errors, hunting a padding-oracle probe, investigating weak cipher negotiation, or fixing nonce reuse or retiring a weak cipher."
---

# Broken Cryptography Implementations - Defensive Methodology

> **Tier 2 - methodology skill.** No bespoke UMBRASEC detection rule ships with this skill yet. It gives the defender's method, the log sources and signals, and the hardening, and points to public rule sources. Promotion to Tier 1 (a sourced, tuned UMBRASEC rule) is tracked in [COVERAGE.md](https://github.com/umbrasec-labs/umbra-blue/blob/main/COVERAGE.md). Do not treat the content below as citing a UMBRASEC rule; there is none for this threat yet.

## TL;DR

Three flaw classes carry nearly all practical cryptographic breaks: unauthenticated CBC that leaks a **padding oracle**, **nonce or IV reuse** (catastrophic for AES-GCM and for any stream cipher), and **weak primitives** (ECB, DES/3DES, RC4, MD5/SHA-1 used for signing, RSA PKCS#1 v1.5, static IVs). Padding-oracle exploitation is the one with a strong runtime signal: it sends thousands of mutated ciphertexts to one endpoint and reads the decrypt outcome from the response, so you see a burst of decryption or padding errors and alternating success/error from a single source against a single parameter. Nonce reuse and weak-primitive misuse are mostly code and TLS-configuration problems with little runtime signal, so the defense is inventory and review, not alerting. Harden by moving to authenticated encryption (AES-GCM or ChaCha20-Poly1305) with unique nonces and strict key rotation, returning uniform constant-time errors so no oracle leaks, retiring weak ciphers in both code and TLS, and keeping crypto libraries patched.

## What it looks like, defender view

A padding-oracle attack presents as a high-volume, low-variety request pattern: the same endpoint and the same single parameter (an encrypted cookie, token, `__VIEWSTATE`, or query value) submitted over and over with its bytes mutated, while every other field stays constant. The server's response distinguishes valid padding from invalid, so defenders see a long run of decryption failures punctuated by the occasional success, all from one client. The classic tell in a .NET stack is a storm of `System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed`; in Java it is `javax.crypto.BadPaddingException`; the ASP.NET ViewState MAC case surfaces as `HttpException: Validation of viewstate MAC failed`. Nonce and IV reuse rarely show in logs at all; its evidence is in captured ciphertext (two messages under one AES-GCM key and nonce, or reused keystream) and in the code or config that generates the nonce. Weak-primitive misuse shows up as the ciphers a service negotiates on the wire and as the algorithm identifiers in the codebase. This skill explains these flaws only as far as detection and mitigation require and shows no technique for exploiting any of them.

## Log sources and signals

The strong runtime signal exists only for oracle-style probing, and only where decryption outcomes are logged. Most environments must add that logging first.

- **Web and reverse-proxy access logs** (IIS, nginx, Apache, HAProxy, AWS ALB, Cloudflare). Key signal: many requests to one URL where a single encrypted parameter, cookie, or header value changes byte by byte while the rest is constant, often with a run of `500`/`400`/`403` responses and the odd `200`/`302`. Fields: client IP, request URI and query, the encrypted parameter length and value, status code, and response size (a size or latency oracle can replace the status code).
- **Application and crypto-library telemetry.** The verifying library is ground truth. Log, as structured events, the exceptions: .NET `CryptographicException` (`Padding is invalid...`), Java `BadPaddingException` and `AEADBadTagException`, Python `cryptography.exceptions.InvalidTag` and `ValueError: Invalid padding`, OpenSSL `bad decrypt`. Include the endpoint, principal, and source IP. `AEADBadTagException`/`InvalidTag` bursts specifically mean authentication-tag failures, which is tampering or an attack on an AEAD mode.
- **ASP.NET event log.** ViewState MAC validation failures (`Validation of viewstate MAC failed`, event source `ASP.NET`) are the historical padding-oracle and tampering signal for MS10-070 (CVE-2010-3332).
- **Network metadata, Zeek `ssl.log` and `x509.log`.** The negotiated `cipher`, `version`, and `validation_status` fields expose weak-primitive exposure directly: TLS 1.0/1.1 or SSLv3, CBC-mode suites, RC4, export suites, and RSA key-exchange (PKCS#1 v1.5) suites. JA3/JA3S hashes help cluster a repeat prober. This is the main durable signal for the weak-primitive and downgrade side.
- **WAF logs** (AWS WAF, ModSecurity CRS, Azure WAF). Useful for rate and pattern signatures on the mutating-parameter behaviour, and as the chokepoint to throttle a prober.

What normal looks like: decryption and padding errors should be near zero in steady state, because legitimate clients send ciphertext the server itself issued. A nonzero baseline that suddenly spikes from one source is the anomaly; a steady trickle usually means a buggy client or expired-token noise to baseline out.

## Detection approach

Detect the oracle probe, not the math. **Threshold decryption and padding failures** grouped by source IP, endpoint, and parameter, and alert when one source drives an abnormal run of such errors against one parameter in a short window; a padding-oracle attack needs roughly 128 to 256 requests per cipher-block byte, so the volume is large and bursty and stands out sharply from baseline. **Correlate alternating outcomes**: a single client producing a long sequence of decrypt failures interleaved with occasional successes against the same parameter is the oracle fingerprint even when individual errors look benign. **Watch the authentication-tag errors** (`AEADBadTagException`, `InvalidTag`) as a distinct, higher-severity class, since they indicate active tampering with authenticated data. **Flag weak negotiation** from Zeek `ssl.log`: alert on SSLv3/TLS 1.0/1.1, RC4, export, and CBC or RSA-key-exchange suites reaching services that should be AEAD and TLS 1.2+ only.

There is no tuned UMBRASEC rule for this threat yet. For public, maintained starting points: the SigmaHQ repository's web and proxy categories at [github.com/SigmaHQ/sigma/tree/master/rules/web](https://github.com/SigmaHQ/sigma/tree/master/rules/web) and its network and Zeek rules at [github.com/SigmaHQ/sigma/tree/master/rules/network](https://github.com/SigmaHQ/sigma/tree/master/rules/network) give scaffolding for the error-burst and weak-cipher signals; padding-oracle logic is usually written against your own verifier telemetry rather than shipped as a generic rule. For TLS posture, use the [Mozilla TLS Observatory / SSL Configuration Generator](https://ssl-config.mozilla.org/) and [testssl.sh](https://testssl.sh/) to enumerate weak negotiation, and the OWASP cryptographic guidance below to define the baseline. MITRE D3FEND's [Message Authentication (D3-MAN)](https://d3fend.mitre.org/technique/d3f:MessageAuthentication/) and [Message Encryption (D3-MENCR)](https://d3fend.mitre.org/technique/d3f:MessageEncryption/) are the countermeasures these detections and the hardening below enforce.

## Threat hunt

Padding oracles and nonce reuse that are exploited slowly, or found by code review before any probing, leave no alert to fire. Hunt across both logs and source.

1. **Oracle-probe fingerprint.** Over a long window, group web/app logs by (source IP, endpoint, encrypted-parameter name) and compute, per group, request count and the ratio of decryption/padding errors to successes. A group with high volume against one parameter and a mixed success/error pattern is the padding-oracle hunt result; triage it directly.
2. **Error correlation.** Pull every `CryptographicException` / `BadPaddingException` / `AEADBadTagException` / `InvalidTag` event and join to the request and client that produced it. Cluster by client and endpoint; `InvalidTag`/`AEADBadTagException` clusters rank highest because they mean integrity-protected data was altered.
3. **Primitive inventory in code.** This is where nonce reuse and weak primitives actually live. Search the codebase and dependencies for `ECB`, `DES`, `DESede`/`3DES`, `RC4`/`ARCFOUR`, `MD5` and `SHA1` used for signatures or MACs, RSA with `PKCS1Padding`/PKCS#1 v1.5, `AES/CBC` without an accompanying MAC or AEAD, hardcoded or zero IV/nonce values, counters that reset per process, and non-cryptographic randomness (`Math.random`, `java.util.Random`, `rand()`) feeding keys, IVs, or nonces. Any AES-GCM nonce derived from a counter that can repeat across restarts, or any static nonce, is a critical finding.
4. **TLS posture.** From Zeek `ssl.log` (or an active scan with testssl.sh), list negotiated `version` and `cipher` per service and flag anything below TLS 1.2 with AEAD, plus RC4, export, CBC, and RSA-key-exchange suites. Rank by exposure and data sensitivity of the service behind each endpoint.

## Hardening

Remove the flaw at the primitive level so no oracle or forgery is possible, then shrink the window for anything that slips through. Mappings below use control codes grounded in the UMBRASEC guide ([foundation.html](https://umbrasec.dev/guide/foundation.html), [detection-and-response.html](https://umbrasec.dev/guide/detection-and-response.html)); a cell is left blank where no single grounded control maps cleanly, which is the case for most primitive-level crypto controls since the guide does not enumerate a dedicated cryptography control.

| Control | What it does | Essential Eight | ISO 27001:2022 | NIST CSF 2.0 |
|---|---|---|---|---|
| Authenticated encryption (AES-GCM, ChaCha20-Poly1305) | Replaces unauthenticated CBC with AEAD so a decrypt never reveals padding validity; the padding oracle ceases to exist and tampering is rejected before plaintext is used | - | - | - |
| Unique nonces and key rotation | Guarantee each nonce/IV is used once per key (random 96-bit or a never-repeating counter), and rotate keys well before the mode's safe message limit; removes GCM and stream-cipher nonce-reuse forgery | - | - | - |
| Retire weak primitives | Remove ECB, DES/3DES, RC4, MD5/SHA-1 signatures, RSA PKCS#1 v1.5, and static IVs from code and from TLS; enforce TLS 1.2+ AEAD-only negotiation | User application hardening | - | - |
| Uniform, constant-time error handling | Return one indistinguishable error for all decrypt/verify failures and compare tags in constant time, so no status, size, or timing oracle leaks | - | - | - |
| Patch crypto libraries | Keep TLS and crypto libraries current; Bleichenbacher/ROBOT, Lucky13, and many padding and tag-check flaws were library defects fixed upstream | Patch applications | A.8.8 Technical vulnerabilities | PR.PS Platform security |
| Approved-primitive inventory and review | Maintain the set of allowed algorithms and modes and gate code review and dependencies against it, so weak primitives cannot reappear | - | A.8.19 Software on systems | PR.PS Platform security |
| Log and monitor crypto failures | Instrument decrypt/verify outcomes and alert on error bursts, so an oracle probe is visible while hardening lands | - | A.8.15 Logging; A.8.16 Monitoring | DE.CM Continuous monitoring |

## Honest limitations

The runtime signal only exists for oracle-style probing that generates failures, and only after you add decryption-outcome logging that most stacks lack by default; without it there is nothing to alert on. A nonce-reuse or weak-primitive flaw exploited against captured ciphertext offline produces no server-side event at all, so it is caught only by the code and TLS hunts, not by detection. A patient attacker can throttle a padding-oracle probe below any error-rate threshold, and a size or timing oracle can replace the status-code signal entirely, defeating a rule keyed on error counts. Error-burst alerting also has a false-positive floor from buggy clients and expired tokens, which must be baselined. None of this substitutes for the fix: an unauthenticated-CBC endpoint, a reused nonce, or a retired-but-still-present cipher is the actual vulnerability, and detection only buys time until AEAD, unique nonces, uniform errors, and a clean primitive set are in place.

## ATT&CK and D3FEND

- MITRE ATT&CK: [T1557 Adversary-in-the-Middle](https://attack.mitre.org/techniques/T1557/) (the position from which chosen-ciphertext and oracle attacks run), [T1600 Weaken Encryption](https://attack.mitre.org/techniques/T1600/) with [T1600.001 Reduce Key Space](https://attack.mitre.org/techniques/T1600/001/) (weak-primitive and downgrade misuse), and [T1040 Network Sniffing](https://attack.mitre.org/techniques/T1040/) (capturing ciphertext for offline attack against reused nonces or weak modes).
- MITRE D3FEND: [Message Authentication (D3-MAN)](https://d3fend.mitre.org/technique/d3f:MessageAuthentication/) enforces integrity so padding and tampering oracles cannot exist; [Message Encryption (D3-MENCR)](https://d3fend.mitre.org/technique/d3f:MessageEncryption/) covers moving to strong authenticated encryption; [Credential Rotation (D3-CRO)](https://d3fend.mitre.org/technique/d3f:CredentialRotation/) covers key rotation ahead of mode limits.
- Standards and public rule sources: [OWASP Top 10 A02:2021 Cryptographic Failures](https://owasp.org/Top10/A02_2021-Cryptographic_Failures/), [OWASP ASVS V11 Cryptography (v5.0; V6 Stored Cryptography in v4.0.3)](https://owasp.org/www-project-application-security-verification-standard/), [NIST SP 800-38D (GCM, nonce-uniqueness requirement)](https://csrc.nist.gov/pubs/sp/800/38/d/final), [RFC 7366 Encrypt-then-MAC for TLS](https://www.rfc-editor.org/rfc/rfc7366), [RFC 8446 TLS 1.3](https://www.rfc-editor.org/rfc/rfc8446), [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/), [SigmaHQ web rules](https://github.com/SigmaHQ/sigma/tree/master/rules/web) and [network rules](https://github.com/SigmaHQ/sigma/tree/master/rules/network).

**Scope note.** This is a defensive skill. It explains padding oracles, nonce reuse, and weak-primitive misuse only to the depth needed to detect and mitigate them and deliberately provides no attack or exploitation tooling. UMBRASEC publishes defense, not offense.
