• Uncategorised

Understanding timing attacks and why constant-time comparison matters

# Why Your Password Comparison is Leaking Secrets

Ever written code like this?

“`java

return storedPassword.equals(providedPassword);

“`

It looks harmless, but it has a critical security flaw. Let me explain.

## The Problem with String.equals()

Java’s `String.equals()` returns `false` the moment it finds the first mismatched character:

“`java

while (n– != 0) {

if (v1[i] != v2[i])

return false; // ⚠️ EARLY EXIT!

i++;

}

“`

This means:

– `”secret”` vs `”aaaaaa”` → fails at index 0 (fast)

– `”secret”` vs `”saaaaa”` → fails at index 1 (slower)

– `”secret”` vs `”seaaaa”` → fails at index 2 (even slower)

**An attacker can measure response times to guess passwords character by character!**

## How Timing Attacks Work

| Guess | Match Length | Response Time |

|——-|————–|—————|

| `axxxx` | 0 chars | ~100ns |

| `sxxxx` | 1 char | ~120ns |

| `sexxx` | 2 chars | ~140ns |

| `secxx` | 3 chars | ~160ns |

By running thousands of attempts and measuring tiny time differences, attackers can recover your passwords without ever seeing them.

## The Fix: Constant-Time Comparison

“`java

private boolean constantTimeEquals(String a, String b) {

byte[] aBytes = a.getBytes(StandardCharsets.UTF_8);

byte[] bBytes = b.getBytes(StandardCharsets.UTF_8);

if (aBytes.length != bBytes.length) {

return false;

}

int result = 0;

for (int i = 0; i < aBytes.length; i++) {

result |= aBytes[i] ^ bBytes[i];

}

return result == 0;

}

“`

**Key difference:** This loop ALWAYS runs through ALL characters. No early exit = no timing leak.

## Built-in Alternatives

Most languages provide secure comparison utilities:

**Java:**

“`java

MessageDigest.isEqual(aBytes, bBytes);

“`

**Node.js:**

“`javascript

crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));

“`

**Python:**

“`python

hmac.compare_digest(a, b)

“`

**PHP:**

“`php

hash_equals($known, $user_input);

“`

## When to Use It

✅ **Always use constant-time comparison for:**

– Passwords

– API keys

– Session tokens

– Any authentication credential

❌ **Regular equals is fine for:**

– Non-sensitive data

– Public information

## Key Takeaway

Security isn’t just about what your code does—it’s about what it reveals while doing it.

Next time you compare credentials, remember: `String.equals()` is fast, but it talks too much.

*Further reading: [OWASP Timing Attack](https://owasp.org/www-community/attacks/Timing_attack) | [CWE-208](https://cwe.mitre.org/data/definitions/208.html)*

You may also like...