Avoid Insecure Cryptography
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:
- Weak hashing: MD5 and SHA1 are vulnerable to collision attacks
- Weak encryption: DES is deprecated due to small key/block sizes
References: CWE-327 (Broken Crypto Algorithm), CWE-328 (Weak Hash), CWE-326 (Inadequate Encryption Strength)
Python
Incorrect (MD5/SHA1 hashing):
import hashlib
hash_val = hashlib.md5(data).hexdigest()
hash_val = hashlib.sha1(data).hexdigest()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)JavaScript
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.
Java
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);Go
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])
}Remediation Summary
| 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 |
Best Practices
- Hashing: Use SHA-256 or SHA-512 for general hashing. For passwords, use bcrypt, scrypt, or Argon2.
- Encryption: Use AES with authenticated modes (GCM, EAX). Avoid ECB mode.
- Key sizes: RSA keys should be at least 2048 bits. AES keys should be 256 bits.
- Random numbers: Use cryptographically secure random number generators for security-sensitive operations.