Skip to content

Java Code Scanning and Semmle LGTM Query Suites Allows for Weak Crypto with BlowFish Key size < 128 #4851

@LordAmit

Description

@LordAmit

The Blowfish cryptographic algorithm is considered secure by CodeQL’s java-code-scanning or java-lgtm-full query suite (reference: https://github.com/github/codeql/blob/main/java/ql/src/semmle/code/java/security/Encryption.qll). However, Blowfish is only considered secure when a key size of greater than 128 is used (reference: https://rules.sonarsource.com/java/RSPEC-4787?search=blowfish ).
Since java-code-scanning or java-lgtm-full query suite do not check for key size they will not flag insecure cryptographic use that uses BlowFish with a key size less than 128.

Here is an example:

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class BlowFish {

    public static void main(String[] args) {
        int keygen_size = 64;
        try {

            KeyGenerator keyGenerator = KeyGenerator.getInstance("Blowfish");
            keyGenerator.init(keygen_size);

            Key key = keyGenerator.generateKey();

            Cipher cipher = Cipher.getInstance("Blowfish/CFB8/NoPadding");

            SecureRandom random = new SecureRandom();
            byte[] iv = new byte[8];
            random.nextBytes(iv);

            IvParameterSpec spec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, key, spec);
            System.out.println(cipher.getBlockSize());
            String plaintext = "Hello World";
            byte[] encrypted = cipher.doFinal(plaintext.getBytes());

            String encrypted_str = new String(encrypted, StandardCharsets.UTF_8);

            System.out.println(encrypted_str);

            Cipher decrypter = Cipher.getInstance("Blowfish/CFB8/NoPadding");
            decrypter.init(Cipher.DECRYPT_MODE, key, spec);

            byte [] retrieved = decrypter.doFinal(encrypted);

            String retrieved_text = new String(retrieved, StandardCharsets.UTF_8);

            System.out.println(retrieved_text);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions