Subchapter 1.14
rules/insecure-crypto.mdMarkdown4 KBView on GitHub
Using weak or broken cryptographic algorithms puts sensitive data at risk. Attackers can exploit known vulnerabilities in deprecated algorithms to decrypt data, forge signatures, or predict “random” values.
Key vulnerabilities:
References: CWE-327 (Broken Crypto Algorithm), CWE-328 (Weak Hash), CWE-326 (Inadequate Encryption Strength)
Incorrect (MD5/SHA1 hashing):
import hashlib
Correct (SHA256 hashing):
import hashlib
hash_val = hashlib.sha256(data).hexdigest()Incorrect (DES cipher):
from Crypto.Cipher import DES
key = b'-8B key-'
cipher = DES.new(key, DES.MODE_CTR, counter=ctr)Correct (AES cipher):
from Crypto.Cipher import AES
key = b'Sixteen byte key'
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)Incorrect (MD5 hashing):
const crypto = require("crypto");
function hashPassword(pwtext) {
return crypto.createHash("md5").update(pwtext).digest("hex");
}Correct (bcrypt for password hashing):
const bcrypt = require("bcrypt");
async function hashPassword(pwtext) {
return bcrypt.hash(pwtext, 12);
}
async function verifyPassword(pwtext, hash) {
return bcrypt.compare(pwtext, hash);
}Note: SHA-256/SHA-512 are fine for data integrity but too fast for password hashing. Use bcrypt, scrypt, or Argon2 for passwords.
Incorrect (MD5/SHA1 hashing):
import java.security.MessageDigest;
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(password.getBytes());
byte[] hash = md5.digest();
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");Correct (BCrypt for password hashing):
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String hash = encoder.encode(password);
boolean matches = encoder.matches(password, hash);Note:
MessageDigest(SHA-256/SHA-512) is appropriate for data integrity checks but not for password storage. Use BCrypt, scrypt, or Argon2 for passwords.
Incorrect (DES cipher):
Cipher c = Cipher.getInstance("DES/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, k);Correct (AES with GCM):
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
c.init(Cipher.ENCRYPT_MODE, k, iv);Incorrect (MD5 hashing):
import (
"crypto/md5"
"fmt"
)
func hashData(data []byte) {
h := md5.New()
h.Write(data)
fmt.Printf("%x", h.Sum(nil))
}Correct (SHA256 hashing):
import (
"crypto/sha256"
"fmt"
)
func hashData(data []byte) {
h := sha256.New()
h.Write(data)
fmt.Printf("%x", h.Sum(nil))
}Incorrect (DES cipher):
import "crypto/des"
func encrypt() {
key := []byte("example key 1234")
block, _ := des.NewCipher(key[:8])
}Correct (AES cipher):
import "crypto/aes"
func encrypt() {
key := []byte("example key 12345678901234567890")
block, _ := aes.NewCipher(key[:32])
}| Language | Weak Algorithm | Secure Alternative |
|---|---|---|
| Python | hashlib.md5, hashlib.sha1 | hashlib.sha256, hashlib.sha512 |
| Python | DES.new() | AES.new() with EAX/GCM mode |
| JavaScript | createHash("md5") | createHash("sha256") |
| Java | getInstance("MD5"), getInstance("SHA-1") | getInstance("SHA-512") |
| Java | getInstance("DES") | getInstance("AES/GCM/NoPadding") |
| Go | crypto/md5, crypto/sha1 | crypto/sha256, crypto/sha512 |
| Go | crypto/des | crypto/aes |