Skip to content

fix: pad HMAC key to 64 bytes to avoid InsecureKeyLengthWarning (#37) - #41

Merged
AaronAtDuo merged 1 commit into
mainfrom
fix-37-insecure-key-length-warning
Aug 27, 2026
Merged

fix: pad HMAC key to 64 bytes to avoid InsecureKeyLengthWarning (#37)#41
AaronAtDuo merged 1 commit into
mainfrom
fix-37-insecure-key-length-warning

Conversation

@AaronAtDuo

Copy link
Copy Markdown
Contributor

Summary

Fixes #37. PyJWT emits an InsecureKeyLengthWarning on every jwt.encode/jwt.decode call because Duo client secrets are 40 bytes, below the 64-byte minimum PyJWT recommends for HS512 (RFC 7518 Section 3.2). This surfaces to users as noisy warnings in their app logs (e.g. Django).

This zero-pads the secret to 64 bytes before using it as the HMAC key. This mirrors the fix already shipped in duo_universal_csharp (PR #23, "Pad the JWT secret out to 64 bytes if necessary").

Why this is safe

HMAC internally zero-pads the key to the hash block size (128 bytes for SHA-512) regardless of input length. A 40-byte key and that same key zero-padded to 64 bytes therefore produce a byte-identical signature. Verified:

  • jwt.encode(payload, secret) == jwt.encode(payload, secret.ljust(64, b'\x00'))
  • A token signed with the raw 40-byte secret still verifies against the padded key

So this stays wire-compatible with Duo's servers (which sign with the 40-byte secret) and preserves the wrong-secret rejection path. self._client_secret is left unchanged; only the derived signing key is padded.

Testing

  • All 77 existing unit tests pass.
  • SDK code paths run clean under -W error::UserWarning — no more InsecureKeyLengthWarning.
  • flake8 clean.

This PR description was generated with AI assistance (Claude).

🤖 Generated with Claude Code

Duo client secrets are 40 bytes, below the 64-byte minimum PyJWT
recommends for HS512 (RFC 7518 Section 3.2), so PyJWT emits an
InsecureKeyLengthWarning on every jwt.encode call.

Zero-pad the secret to 64 bytes before using it as the HMAC key.
HMAC zero-pads the key to the hash block size (128 bytes for SHA-512)
regardless, so this produces a byte-identical signature and remains
wire-compatible with Duo while silencing the warning. This mirrors the
fix in the duo_universal_csharp library (PR #23).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@AaronAtDuo
AaronAtDuo enabled auto-merge (squash) August 27, 2026 16:24
@AaronAtDuo
AaronAtDuo merged commit 77158bb into main Aug 27, 2026
6 checks passed
@AaronAtDuo
AaronAtDuo deleted the fix-37-insecure-key-length-warning branch August 27, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InsecureKeyLengthWarning in Django apps

2 participants