kotlin.lang.security.gcm-detection.gcm-detection

Author
unknown
Download Count*
License
GCM detected, please check that IV/nonce is not reused, an Initialization Vector (IV) is a nonce used to randomize the encryption, so that even if multiple messages with identical plaintext are encrypted, the generated corresponding ciphertexts are different.Unlike the Key, the IV usually does not need to be secret, rather it is important that it is random and unique. Certain encryption schemes the IV is exchanged in public as part of the ciphertext. Reusing same Initialization Vector with the same Key to encrypt multiple plaintext blocks allows an attacker to compare the ciphertexts and then, with some assumptions on the content of the messages, to gain important information about the data being encrypted.
Run Locally
Run in CI
Defintion
rules:
- id: gcm-detection
metadata:
category: security
cwe:
- "CWE-323: Reusing a Nonce, Key Pair in Encryption"
references:
- https://cwe.mitre.org/data/definitions/323.html
technology:
- kotlin
license: Commons Clause License Condition v1.0[LGPL-2.1-only]
owasp:
- A02:2021 - Cryptographic Failures
subcategory:
- audit
likelihood: LOW
impact: LOW
confidence: LOW
vulnerability_class:
- Cryptographic Issues
languages:
- kt
message: GCM detected, please check that IV/nonce is not reused, an
Initialization Vector (IV) is a nonce used to randomize the encryption, so
that even if multiple messages with identical plaintext are encrypted, the
generated corresponding ciphertexts are different.Unlike the Key, the IV
usually does not need to be secret, rather it is important that it is
random and unique. Certain encryption schemes the IV is exchanged in
public as part of the ciphertext. Reusing same Initialization Vector with
the same Key to encrypt multiple plaintext blocks allows an attacker to
compare the ciphertexts and then, with some assumptions on the content of
the messages, to gain important information about the data being
encrypted.
patterns:
- pattern-either:
- pattern: $METHOD.getInstance("AES/GCM/NoPadding",...)
- pattern: GCMParameterSpec(...)
severity: INFO
Examples
gcm-detection.kt
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.GCMParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.util.Base64
public class GcmHardcodedIV
{
fun byteArrayOfInts(vararg ints: Int) = Array<Byte>(ints.size) { pos -> ints[pos].toByte() }
public final val GCM_TAG_LENGTH: Int = 16
public final val BAD_IV: String = "ab0123456789"
public final val BAD_IV2 = byteArrayOfInts(0,1,2,3,4,5,6,7,8,9,10,11)
private val theIV: Array<Byte>
private val theKey: SecretKey
public fun main(args: Array<String>) : Void
{
val clearText: String = args[0]
System.out.println(clearText)
try {
setKeys()
val cipherText: String = encrypt(clearText)
System.out.println(cipherText)
val decrypted: String = decrypt(cipherText)
System.out.println(decrypted)
} catch(e: Exception) {
System.out.println(e.getMessage())
}
}
public fun encrypt(clearText: String): String {
// ruleid:gcm-detection
val cipher: Cipher = Cipher.getInstance("AES/GCM/NoPadding")
val keySpec: SecretKeySpec= SecretKeySpec(theKey.getEncoded(), "AES")
val theBadIV: Array<Byte> = BAD_IV.getBytes()
// ruleid:gcm-detection
val gcmParameterSpec: GCMParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH * 8, theBadIV)
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmParameterSpec)
val cipherText: Array<Byte> = cipher.doFinal(clearText.getBytes())
val encoded = base64.getEncoder().encodeToString(cipherText)
return encoded
}
public fun decrypt(cipherText: String): String {
// ruleid:gcm-detection
val cipher: Cipher = Cipher.getInstance("AES/GCM/NoPadding")
val keySpec: SecretKeySpec = SecretKeySpec(theKey.getEncoded(), "AES")
// ruleid:gcm-detection
val gcmParameterSpec: GCMParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH * 8, theIV)
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec)
val decoded: Array<Byte> = Base64.getDecoder().decode(cipherText)
val decryptedText: Array<Byte> = cipher.doFinal(decoded)
return String(decryptedText)
}
public fun setKeys(): Void {
val keyGenerator: KeyGenerator = KeyGenerator.getInstance("AES")
keyGenerator.init(256)
theIV = BAD_IV.getBytes()
}
}
Short Link: https://sg.run/WpPA