Skip to content

MASTG-DEMO-0017: Use of Hardcoded AES Key in SecretKeySpec with semgrep

Download MASTG-DEMO-0017 APK Open MASTG-DEMO-0017 Folder Build MASTG-DEMO-0017 APK

Sample

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package org.owasp.mastestapp

import android.content.Context
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec
import android.util.Base64

class MastgTest(private val context: Context) {

    fun mastgTest(): String {

        // Bad: Use of a hardcoded key (from bytes) for encryption
        val keyBytes = byteArrayOf(0x6C, 0x61, 0x6B, 0x64, 0x73, 0x6C, 0x6A, 0x6B, 0x61, 0x6C, 0x6B, 0x6A, 0x6C, 0x6B, 0x6C, 0x73) // Example key bytes
        val cipher = Cipher.getInstance("AES/GCM/NoPadding")
        val secretKey = SecretKeySpec(keyBytes, "AES")
        cipher.init(Cipher.ENCRYPT_MODE, secretKey)

        // Bad: Hardcoded key directly in code (security risk)
        val badSecretKeySpec = SecretKeySpec("my secret here".toByteArray(), "AES")


        // Returning results
        return "SUCCESS!!\n\nThe keys were generated and used successfully with the following details:\n\n" +
                "Hardcoded AES Encryption Key: ${Base64.encodeToString(keyBytes, Base64.DEFAULT)}\n" +
                "Hardcoded Key from string: ${Base64.encodeToString(badSecretKeySpec.encoded, Base64.DEFAULT)}\n"
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package org.owasp.mastestapp;

import android.content.Context;
import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import kotlin.text.Charsets;

/* compiled from: MastgTest.kt */
@Metadata(d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\b\u0007\u0018\u00002\u00020\u0001B\r\u0012\u0006\u0010\u0002\u001a\u00020\u0003¢\u0006\u0002\u0010\u0004J\u0006\u0010\u0005\u001a\u00020\u0006R\u000e\u0010\u0002\u001a\u00020\u0003X\u0082\u0004¢\u0006\u0002\n\u0000¨\u0006\u0007"}, d2 = {"Lorg/owasp/mastestapp/MastgTest;", "", "context", "Landroid/content/Context;", "(Landroid/content/Context;)V", "mastgTest", "", "app_debug"}, k = 1, mv = {1, 9, 0}, xi = 48)
/* loaded from: classes4.dex */
public final class MastgTest {
    public static final int $stable = 8;
    private final Context context;

    public MastgTest(Context context) {
        Intrinsics.checkNotNullParameter(context, "context");
        this.context = context;
    }

    public final String mastgTest() {
        byte[] keyBytes = {108, 97, 107, 100, 115, 108, 106, 107, 97, 108, 107, 106, 108, 107, 108, 115};
        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
        cipher.init(1, secretKey);
        byte[] bytes = "my secret here".getBytes(Charsets.UTF_8);
        Intrinsics.checkNotNullExpressionValue(bytes, "this as java.lang.String).getBytes(charset)");
        SecretKeySpec badSecretKeySpec = new SecretKeySpec(bytes, "AES");
        return "SUCCESS!!\n\nThe keys were generated and used successfully with the following details:\n\nHardcoded AES Encryption Key: " + Base64.encodeToString(keyBytes, 0) + "\nHardcoded Key from string: " + Base64.encodeToString(badSecretKeySpec.getEncoded(), 0) + '\n';
    }
}

Steps

Let's run our semgrep rule against the sample code.

../../../../rules/mastg-android-hardcoded-crypto-keys-usage.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
rules:
  - id: mastg-android-hardcoded-crypto-keys-usage
    severity: WARNING
    languages:
      - java
    metadata:
      summary: This rule looks for hardcoded keys in use.
    message: "[MASVS-CRYPTO-1] Hardcoded cryptographic keys found in use."
    pattern-either:
      - pattern: SecretKeySpec $_ = new SecretKeySpec($KEY, $ALGO);
      - pattern: |-
          byte[] $KEY = {...};
          ...
          new SecretKeySpec($KEY, $ALGO);
run.sh
1
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-hardcoded-crypto-keys-usage.yml ./MastgTest_reversed.java --text -o output.txt

Observation

The rule has identified one instance in the code file where hardcoded keys is used. The specified line numbers can be located in the reverse-engineered code for further investigation and remediation.

output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
┌─────────────────┐
 3 Code Findings 
└─────────────────┘

    MastgTest_reversed.java
   ❯❯❱ hardcoded-crypto-key-test
          Hardcoded cryptographic keys are found in use.

           24 byte[] keyBytes = {108, 97, 107, 100, 115, 108, 106, 107, 97, 108, 107, 106, 108, 107, 108,
               115};                                                                                      
           25 Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
           26 SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            ⋮┆----------------------------------------
           26 SecretKeySpec secretKey = new SecretKeySpec(keyBytes, "AES");
            ⋮┆----------------------------------------
           30 SecretKeySpec badSecretKeySpec = new SecretKeySpec(bytes, "AES");                

Evaluation

The test fails because hardcoded cryptographic keys are present in the code. Specifically:

  • On line 24, a byte array that represents a cryptographic key is directly hardcoded into the source code.
  • This hardcoded key is then used on line 26 to create a SecretKeySpec.
  • Additionally, on line 30, another instance of hardcoded data is used to create a separate SecretKeySpec.