Weak Encryption Mode of Operation
ID |
swift.weak_encryption_mode_of_operation |
Severity |
critical |
Resource |
Cryptography |
Language |
Swift |
Tags |
CWE:327, MASWE:0020, NIST.SP.800-53, OWASP:2021:A2, PCI-DSS:6.5.3, crypto |
Description
The use of weak encryption modes of operation, such as ECB, can compromise the confidentiality and integrity of data by allowing patterns to be detected in encrypted data. This is particularly pertinent in applications where secure encryption practices are crucial for protecting sensitive information.
Rationale
Certain encryption modes like Electronic Codebook (ECB) are considered weak because they encrypt identical plaintext blocks into identical ciphertext blocks.
This lack of semantic security may lead to pattern detection, data leakage, or could aid attackers in deciphering the content. Using stronger modes such as Cipher Block Chaining (CBC) or Galois/Counter Mode (GCM) enhances security by introducing an initialization vector (IV) or nonce, ensuring that ciphertext appears random even when plaintexts are identical.
In Swift, using ECB mode is a critical vulnerability:
import CryptoSwift
func encryptWithECB(_ plaintext: String, key: [UInt8]) throws -> [UInt8] {
// FLAW: ECB mode reveals patterns in plaintext
let blockMode = ECB() // FLAW
let aes = try AES(key: key, blockMode: blockMode, padding: .pkcs7)
return try aes.encrypt(Array(plaintext.utf8))
}
Another vulnerable example with Blowfish:
import CryptoSwift
func encryptBlowfishECB(_ data: Data, key: [UInt8]) throws -> [UInt8] {
// FLAW: ECB mode with Blowfish
let blockMode = ECB() // FLAW
let blowfish = try Blowfish(key: key, blockMode: blockMode, padding: .pkcs7)
return try blowfish.encrypt([UInt8](data))
}
Remediation
To remediate the use of weak encryption modes, it is advisable to use secure modes such as CBC or GCM, which require an IV or nonce, thus preventing pattern detection and data leakage. Below is an example using AES-128-CBC with a random IV:
For Swift, use secure modes with proper IV / nonce generation:
import CryptoSwift
struct EncryptedData {
let ciphertext: [UInt8]
let iv: [UInt8]
}
func encryptWithCBC(_ plaintext: String, key: [UInt8]) throws -> EncryptedData {
// FIXED: CBC mode with random IV
let iv = (0..<AES.blockSize).map { _ in UInt8.random(in: 0...UInt8.max) }
let blockMode = CBC(iv: iv) // FIXED
let aes = try AES(key: key, blockMode: blockMode, padding: .pkcs7)
let ciphertext = try aes.encrypt(Array(plaintext.utf8))
return EncryptedData(ciphertext: ciphertext, iv: iv)
}
Better yet, use CryptoKit with AES-GCM (AEAD):
import CryptoKit
import Foundation
func encryptWithAESGCM(_ plaintext: Data, key: SymmetricKey) throws -> Data {
// FIXED: AES-GCM provides authenticated encryption
let sealedBox = try AES.GCM.seal(plaintext, using: key)
// Combined data includes nonce, ciphertext, and authentication tag
return sealedBox.combined!
}
func decryptWithAESGCM(_ combined: Data, key: SymmetricKey) throws -> Data {
let sealedBox = try AES.GCM.SealedBox(combined: combined)
return try AES.GCM.open(sealedBox, using: key)
}
Using ChaCha20-Poly1305 for authenticated encryption:
import CryptoKit
import Foundation
func encryptWithChaCha20Poly1305(_ plaintext: Data, key: SymmetricKey) throws -> Data {
// FIXED: ChaCha20-Poly1305 provides authenticated encryption
let nonce = try ChaChaPoly.Nonce(data: Data(count: 12))
let sealedBox = try ChaChaPoly.seal(plaintext, using: key, nonce: nonce)
return sealedBox.combined
}
func decryptWithChaCha20Poly1305(_ combined: Data, key: SymmetricKey) throws -> Data {
let sealedBox = try ChaChaPoly.SealedBox(combined: combined)
return try ChaChaPoly.open(sealedBox, using: key)
}
Configuration
The detector has the following configurable parameters:
-
forbiddenModes, that indicates the modes that are considered weak and that should not be used.
Example configuration:
properties:
forbiddenModes:
- ECB # Electronic Codebook - never secure
- CTR # Counter mode - dangerous without proper nonce management
References
-
CWE-327 : Use of a Broken or Risky Cryptographic Algorithm.
-
MASWE-0020: Improper Encryption.
-
Block cipher modes of operation, Wikipedia