Use a dynamically-generated, random IV

I have a false positive, in my work i can’t do an exception, I’m not en expert but i think that this code is correct:

This Work (“Threefish-1024/CBC/ISO10126Padding”).

private static String encryptImpl(final String key, final String message) throws
            UnsupportedEncodingException,
            NoSuchAlgorithmException,
            NoSuchProviderException,
            NoSuchPaddingException,
            InvalidKeyException,
            InvalidAlgorithmParameterException,
            IllegalBlockSizeException,
            BadPaddingException {
        String result = StringUtils.EMPTY;
        if (StringUtils.isNotBlank(key) && StringUtils.isNotEmpty(message)) {
            byte[] biv = new byte[IV_SIZE];

            SecureRandom sr = SecureRandom.getInstanceStrong();
            sr.nextBytes(biv);

            final String hexIv = Hex.encodeHexString(biv);
            IvParameterSpec iv = new IvParameterSpec(biv);

            byte[] data = key.getBytes(StandardCharsets.UTF_8);
            Security.addProvider(new BouncyCastleProvider());
            SecretKeySpec ks = new SecretKeySpec(data, ALGORITHM);
            Cipher cipher = Cipher.getInstance(OPERATION_MODE, "BC");
            cipher.init(Cipher.ENCRYPT_MODE, ks, iv);
            byte[] out = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
            final String hexSecret = Hex.encodeHexString(out);
            result = String.format("%s%s", hexIv, hexSecret);
        }
        return result;
    }

This don’t work (note: biv is obtained form encrypted string)

private static String decryptImpl(final String key, final byte[] biv, final String message) throws
            UnsupportedEncodingException,
            NoSuchAlgorithmException,
            NoSuchProviderException,
            NoSuchPaddingException,
            InvalidKeyException,
            InvalidAlgorithmParameterException,
            IllegalBlockSizeException,
            BadPaddingException,
            DecoderException {
        String result = StringUtils.EMPTY;
        if (StringUtils.isNotBlank(key) && StringUtils.isNotEmpty(message)) {
            final IvParameterSpec iv = new IvParameterSpec(biv);

            byte[] data = key.getBytes(StandardCharsets.UTF_8);
            Security.addProvider(new BouncyCastleProvider());
            SecretKeySpec ks = new SecretKeySpec(data, ALGORITHM);
            Cipher cipher = Cipher.getInstance(OPERATION_MODE, "BC");
            cipher.init(Cipher.DECRYPT_MODE, ks, iv);
            byte[] out = cipher.doFinal(Hex.decodeHex(message.toCharArray()));
            result = new String(out);
        }
        return result;
    }

Hi Sebastián and welcome to the community!

Your code looks indeed fine. The IV should only be randomly generated when encrypting but of course for the decrypting part that is not possible, since it has to match the IV that was used for encrypting.

In some cases it is not easily possible for us to determine if the code will encrypt or decrypt but in this case it should be no problem. I have created the ticket SONARJAVA-4122 to fix the issue. Thanks for the report!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.