Quantum Readiness

Broken today, no quantum computer needed.

MD5 on a password, ECB mode or a disabled certificate check can be exploited now. NightVision finds these choices in your code and settings, rates each one by the role it plays, and names what to use instead.

Weak cryptography is a cryptographic choice an attacker can exploit with today's computers: a broken algorithm such as MD5, DES or RC4, a deprecated one such as 3DES or TLS 1.0, a sound primitive used unsoundly, such as AES in ECB mode or an IV written into the source, or verification switched off. NightVision sorts these into five classes and rates each finding by what the algorithm does where it is used, so a cache key does not rank with a password.

Five Classes

Five ways cryptography goes wrong before quantum

The same pass that finds quantum-vulnerable choices reports these. Severity follows the risk: what an attacker can do with the choice today.

ClassWhat it meansExamplesSeverity
Broken Practical attacks are known. MD5 and SHA-1 digests and signatures, DES, RC4, SSL 2.0 and 3.0, JWT alg of none, plaintext or fast-hash password storage, NULL and export cipher suites, RSA below 1024 bits
High
A digest is high only when it hashes a secret, low otherwise
Deprecated Below current minimums: NIST SP 800-131A disallows it, or the IETF has retired it. 3DES, RC2, Blowfish, CAST5, IDEA, RSA and DH below 2048 bits, curves below 224 bits, DSA, TLS 1.0 and 1.1, HMAC-MD5, HMAC-SHA-1 and SHA-224
MediumLow
Misuse A sound primitive used unsoundly. ECB mode, an IV written in the source, RSA PKCS #1 v1.5 encryption, fewer than 10,000 PBKDF2 iterations, certificate, host name or token signature verification turned off, OpenSSL security level below 2
HighMedium
Unvalidated implementation A standard algorithm written by hand in the tree instead of taken from a validated library. A hand-written MD5, an AES S-box in the application's own code
Medium
Unapproved library A cryptography library outside the approved set. An inventory item to review, not a fault. CryptoJS, PyCrypto, pyDes, mcrypt, phpseclib 1.x
Info
Role-Aware

Same algorithm, different verdict

"SHA-1 found" is not something anyone can act on. What matters is what the algorithm does at that line, so NightVision assesses each choice where a call consumes it, by the role it plays there.

AlgorithmSHA-1
As a digest or signature hash hashlib.sha1(password)
brokenHigh

High when the call hashes a password, secret or token. Low for a cache key or a file name. Medium as the hash of a signature in code.

As an HMAC hash hmac.new(key, msg, hashlib.sha1)
deprecated

HMAC-SHA-1 has no practical break, but it is below current minimums and has a NIST retirement date.

As OAEP's hash padding.OAEP(algorithm=hashes.SHA1(), ...)
Not reported

Inside RSA-OAEP padding, SHA-1 raises nothing.

PaddingPKCS1v15
For encryption key.encrypt(data, padding.PKCS1v15())
misuse

RSA PKCS #1 v1.5 encryption is weak. Use RSAES-OAEP.

For a signature key.sign(data, padding.PKCS1v15(), hashes.SHA256())
No padding finding

The same padding is sound for a signature, so it is not reported where it is built.

Sensitive Input

A digest is high only when it hashes a secret

Most MD5 and SHA-1 calls in real applications key a cache, name a file or deduplicate records. Rating every one of them high buries the one that hashes a password.

NightVision raises a broken digest to high only when the call names the data it hashes as a password, a secret or a token: an argument such as password, user_pwd, clientSecret, apiKey or token_data. The finding records input as sensitive. Any other broken digest is low.

Hashing a password with any fast hash is a misuse, but only a broken one (MD2, MD4, MD5 or SHA-1) is raised to high for it. The judgment reads the names at the call, so md5() followed later by update(password) is rated low.

hashlib.md5(password)
Highinput: sensitive
hashlib.sha1(token_data)
Highinput: sensitive
hashlib.md5(cache_key)
Low
hashlib.md5(data, usedforsecurity=False)
Not reported
hashlib.sha224(password)
Lowdeprecated
Fixes

What it flags, and what to write instead

Each finding carries its remediation. A sample of what the Python rules catch:

DES.new(key, DES.MODE_CBC, iv)broken

Instead: AES in an authenticated mode such as GCM, or ChaCha20-Poly1305. The same holds for RC4 and 3DES.

Cipher(algorithms.AES(key), modes.ECB())misuse

Instead: an authenticated mode such as AES-GCM. ECB encrypts equal blocks to equal ciphertext.

modes.CBC(b"0123456789abcdef")misuse

Instead: a fresh IV for every message, not one written in the source.

hashlib.pbkdf2_hmac("sha256", pw, salt, 1000)misuse

Instead: a password hash at OWASP's current cost. Under 10,000 PBKDF2 iterations is flagged.

requests.get(url, verify=False)misuse

Instead: leave certificate verification on. httpx and aiohttp calls are read too, and so is check_hostname = False on an ssl context.

jwt.decode(t, key, options={"verify_signature": False})misuse

Instead: verify the token's signature, with an explicit list of allowed algorithms.

jwt.encode(claims, key, algorithm="none")broken

Instead: sign every token. An unsigned JWT can be forged by anyone.

ssl.SSLContext(ssl.PROTOCOL_TLSv1)deprecated

Instead: TLS 1.2 or later. TLS 1.0 and 1.1 in nginx, Apache and OpenSSL configuration are flagged too.

Signal Over Noise

What it leaves out, on purpose

A report that flags every hash call gets ignored. These are not reported, so what remains needs a change:

  • AES and ChaCha20 with 128-bit keys or more, SHA-256 and above, and HMAC-SHA-256.
  • A digest called with usedforsecurity=False, which declares it is not a security use.
  • A choice the source does not fix: one read from the environment with no default, from a file, or from a vault.
  • Apache's all, which admits whatever the linked OpenSSL admits rather than a choice the file makes.

Lines a developer marked for another tool with nosec, nosemgrep or a flake8-bandit noqa are still reported, with the marker named, so you can hide accepted findings deliberately instead of losing them.

Code and framework settings are read in Python today: hashlib, hmac, pyca/cryptography, PyCryptodome and PyCrypto, ssl, requests, httpx and aiohttp verification, PyJWT, python-jose, jwcrypto, passlib, Django, Flask-JWT-Extended and Flask-Security. Committed keys, TLS configuration, dependency manifests and hand-written algorithms are read in any language; see keys, certificates and TLS.

Where It Runs

In the NightVision CLI, beside your API spec

Add --weak-crypto to nightvision openapi extract and the report is written beside the API spec that source intelligence generates. A default run uploads the spec and the report to NightVision, and --no-upload sends nothing. Source code is never uploaded, and no language model reads it. Viewing and tracking these findings in the NightVision platform is in development.

FAQ

Questions about weak cryptography.

What is weak cryptography?

A cryptographic choice an attacker can exploit with today's computers: a broken or deprecated algorithm, a sound primitive used unsoundly, a standard algorithm written by hand, or verification turned off. It needs fixing now, whatever the quantum timeline.

Is SHA-1 always flagged?

No. SHA-1 is broken as a digest or a signature hash, deprecated as an HMAC hash, and not reported as the hash inside RSA-OAEP. NightVision rates it by the role it plays where it is used.

Why is my MD5 finding rated low?

A broken digest is rated high only when the call names the data it hashes as a password, a secret or a token. Most MD5 and SHA-1 digests key a cache, name a file or deduplicate records, so those are rated low.

Does NightVision flag AES or SHA-256?

No. AES and ChaCha20 with 128-bit keys or more, and SHA-256 and above, are not reported. AES in ECB mode, or with an IV written in the source, is reported as a misuse.

Which languages are covered?

Code and framework settings are analyzed in Python today. Committed keys, certificates, TLS configuration, dependency manifests and hand-written algorithms are read in any language.

Where does this run today?

It runs in the NightVision CLI today: add the --weak-crypto flag to nightvision openapi extract and the report is written beside the API spec that source intelligence generates. The --no-upload flag sends nothing to NightVision. Viewing and tracking these findings in the NightVision platform is in development.

Fix what is broken now.

Find the weak cryptography in your code and committed files, rated by what it protects, with what to use instead. Then plan for what quantum breaks.