Java AES encryption and decryption

AES encryption

The Advanced Encryption Standard (AES, Rijndael) is a block cipher encryption and decryption algorithm, the most used encryption algorithm in the worldwide. The AES processes block of 128 bits using a secret key of 128, 192, or 256 bits.

This article shows you a few of Java AES encryption and decryption examples:

  • AES String encryption – (encrypt and decrypt a string).
  • AES Password-based encryption – (The secret key will derive from a given password).
  • AES File encryption. (password-based).

In this article, we are focus on the 256-bit AES encryption with Galois Counter Mode (GCM).


GCM = CTR + Authentication.

Further Reading
Read this – NIST – Recommendation for Galois/Counter Mode (GCM)

Don’t use AES Electronic codebook (ECB) Mode
The AES ECB mode, or AES/ECB/PKCS5Padding (in Java) is not semantically secure – The ECB-encrypted ciphertext can leak information about the plaintext. Here is a discussion about Why shouldn’t I use ECB encryption?

1. Java and AES encryption inputs.

In AES encryption and decryption, we need the following inputs:

AES encryption best practice
Don’t reuse IV with the same key.

1.1 The IV (initial value or initial vector), it is random bytes, typically 12 bytes or 16 bytes. In Java, we can use SecureRandom to generate the random IV.


  // 16 bytes IV
  public static byte[] getRandomNonce() {
        byte[] nonce = new byte[16];
        new SecureRandom().nextBytes(nonce);
        return nonce;
  }

  // 12 bytes IV
  public static byte[] getRandomNonce() {
        byte[] nonce = new byte[12];
        new SecureRandom().nextBytes(nonce);
        return nonce;
  }

1.2 The AES secret key, either AES-128 or AES-256. In Java, we can use KeyGenerator to generate the AES secret key.


    // 256 bits AES secret key
    public static SecretKey getAESKey() throws NoSuchAlgorithmException {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(256, SecureRandom.getInstanceStrong());
        return keyGen.generateKey();
    }

1.3 The AES secret key that derived from a given password. In Java, we can use the SecretKeyFactory and PBKDF2WithHmacSHA256 to generate an AES key from a given password.


    // AES key derived from a password
    public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        // iterationCount = 65536
        // keyLength = 256
        KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
        return secret;
    }

We use salt to protect rainbow attacks, and it is also a random byte, we can use the same 1.1 getRandomNonce to generate it.

1.4 We group the above methods into a single util class, so that we won’t repeat the same code again and again.

CryptoUtils.java

package com.mkyong.crypto.utils;

import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.ArrayList;
import java.util.List;

public class CryptoUtils {

    public static byte[] getRandomNonce(int numBytes) {
        byte[] nonce = new byte[numBytes];
        new SecureRandom().nextBytes(nonce);
        return nonce;
    }

    // AES secret key
    public static SecretKey getAESKey(int keysize) throws NoSuchAlgorithmException {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(keysize, SecureRandom.getInstanceStrong());
        return keyGen.generateKey();
    }

    // Password derived AES 256 bits secret key
    public static SecretKey getAESKeyFromPassword(char[] password, byte[] salt)
            throws NoSuchAlgorithmException, InvalidKeySpecException {

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        // iterationCount = 65536
        // keyLength = 256
        KeySpec spec = new PBEKeySpec(password, salt, 65536, 256);
        SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
        return secret;

    }

    // hex representation
    public static String hex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    // print hex with block size split
    public static String hexWithBlockSize(byte[] bytes, int blockSize) {

        String hex = hex(bytes);

        // one hex = 2 chars
        blockSize = blockSize * 2;

        // better idea how to print this?
        List<String> result = new ArrayList<>();
        int index = 0;
        while (index < hex.length()) {
            result.add(hex.substring(index, Math.min(index + blockSize, hex.length())));
            index += blockSize;
        }

        return result.toString();

    }

}

2. AES encryption and decryption.

The AES-GSM is the most widely used authenticated cipher. This example will encrypt and decrypt a string using 256-bit AES in Galois Counter Mode (GCM).

The AES-GCM inputs:

  • AES Secret key (256 bits)
  • IV – 96 bits (12 bytes)
  • Length (in bits) of authentication tag – 128 bits (16 bytes)

2.1 In Java, we use AES/GCM/NoPadding to represent the AES-GCM algorithm. For the encrypted output, we prefix the 16 bytes IV to the encrypted text (ciphertext), because we need the same IV for decryption.

Is this ok if IV is publicly known?
It is ok for IV to be publicly known, the only secret is the key, keep it private and confidential.

This example will use AES to encrypt a plain text Hello World AES-GCM and later decrypt it back to the original plain text.

EncryptorAesGcm.java

package com.mkyong.crypto.encryptor;

import com.mkyong.crypto.utils.CryptoUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * AES-GCM inputs - 12 bytes IV, need the same IV and secret keys for encryption and decryption.
 * <p>
 * The output consist of iv, encrypted content, and auth tag in the following format:
 * output = byte[] {i i i c c c c c c ...}
 * <p>
 * i = IV bytes
 * c = content bytes (encrypted content, auth tag)
 */
public class EncryptorAesGcm {

    private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding";
    private static final int TAG_LENGTH_BIT = 128;
    private static final int IV_LENGTH_BYTE = 12;
    private static final int AES_KEY_BIT = 256;

    private static final Charset UTF_8 = StandardCharsets.UTF_8;

    // AES-GCM needs GCMParameterSpec
    public static byte[] encrypt(byte[] pText, SecretKey secret, byte[] iv) throws Exception {

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
        cipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
        byte[] encryptedText = cipher.doFinal(pText);
        return encryptedText;

    }

    // prefix IV length + IV bytes to cipher text
    public static byte[] encryptWithPrefixIV(byte[] pText, SecretKey secret, byte[] iv) throws Exception {

        byte[] cipherText = encrypt(pText, secret, iv);

        byte[] cipherTextWithIv = ByteBuffer.allocate(iv.length + cipherText.length)
                .put(iv)
                .put(cipherText)
                .array();
        return cipherTextWithIv;

    }

    public static String decrypt(byte[] cText, SecretKey secret, byte[] iv) throws Exception {

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);
        cipher.init(Cipher.DECRYPT_MODE, secret, new GCMParameterSpec(TAG_LENGTH_BIT, iv));
        byte[] plainText = cipher.doFinal(cText);
        return new String(plainText, UTF_8);

    }

    public static String decryptWithPrefixIV(byte[] cText, SecretKey secret) throws Exception {

        ByteBuffer bb = ByteBuffer.wrap(cText);

        byte[] iv = new byte[IV_LENGTH_BYTE];
        bb.get(iv);
        //bb.get(iv, 0, iv.length);

        byte[] cipherText = new byte[bb.remaining()];
        bb.get(cipherText);

        String plainText = decrypt(cipherText, secret, iv);
        return plainText;

    }

    public static void main(String[] args) throws Exception {

        String OUTPUT_FORMAT = "%-30s:%s";

        String pText = "Hello World AES-GCM, Welcome to Cryptography!";

        // encrypt and decrypt need the same key.
        // get AES 256 bits (32 bytes) key
        SecretKey secretKey = CryptoUtils.getAESKey(AES_KEY_BIT);

        // encrypt and decrypt need the same IV.
        // AES-GCM needs IV 96-bit (12 bytes)
        byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE);

        byte[] encryptedText = EncryptorAesGcm.encryptWithPrefixIV(pText.getBytes(UTF_8), secretKey, iv);

        System.out.println("\n------ AES GCM Encryption ------");
        System.out.println(String.format(OUTPUT_FORMAT, "Input (plain text)", pText));
        System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));
        System.out.println(String.format(OUTPUT_FORMAT, "IV  (hex)", CryptoUtils.hex(iv)));
        System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) ", CryptoUtils.hex(encryptedText)));
        System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));

        System.out.println("\n------ AES GCM Decryption ------");
        System.out.println(String.format(OUTPUT_FORMAT, "Input (hex)", CryptoUtils.hex(encryptedText)));
        System.out.println(String.format(OUTPUT_FORMAT, "Input (hex) (block = 16)", CryptoUtils.hexWithBlockSize(encryptedText, 16)));
        System.out.println(String.format(OUTPUT_FORMAT, "Key (hex)", CryptoUtils.hex(secretKey.getEncoded())));

        String decryptedText = EncryptorAesGcm.decryptWithPrefixIV(encryptedText, secretKey);

        System.out.println(String.format(OUTPUT_FORMAT, "Decrypted (plain text)", decryptedText));

    }

}

Output

Plain Text : Hello World AES-GCM

Terminal

------ AES GCM Encryption ------
Input (plain text)            :Hello World AES-GCM
Key (hex)                     :603d87185bf855532f14a77a91ec7b025c004bf664e9f5c6e95613ee9577f436
IV  (hex)                     :bdb271ce5235996a0709e09c
Encrypted (hex)               :bdb271ce5235996a0709e09c2d03eefe319e9329768724755c56291aecaef88cd1e6bdf72b8c7b54d75a94e66b0cd3
Encrypted (hex) (block = 16)  :[bdb271ce5235996a0709e09c2d03eefe, 319e9329768724755c56291aecaef88c, d1e6bdf72b8c7b54d75a94e66b0cd3]

------ AES GCM Decryption ------
Input (hex)                   :bdb271ce5235996a0709e09c2d03eefe319e9329768724755c56291aecaef88cd1e6bdf72b8c7b54d75a94e66b0cd3
Input (hex) (block = 16)      :[bdb271ce5235996a0709e09c2d03eefe, 319e9329768724755c56291aecaef88c, d1e6bdf72b8c7b54d75a94e66b0cd3]
Key (hex)                     :603d87185bf855532f14a77a91ec7b025c004bf664e9f5c6e95613ee9577f436
Decrypted (plain text)        :Hello World AES-GCM

Plain Text : Hello World AES-GCM, Welcome to Cryptography!

Terminal

------ AES GCM Encryption ------
Input (plain text)            :Hello World AES-GCM, Welcome to Cryptography!
Key (hex)                     :ddc24663d104e1c2f81f11aef98156503dafdc435f81e3ac3d705015ebab095c
IV  (hex)                     :b05d6aedf023f73b9e1e2d11
Encrypted (hex)               :b05d6aedf023f73b9e1e2d11f6f5137d971aea8c5cdd5b045e0960eb4408e0ee4635cccc2dfeec2c13a89bd400f659be82dc2329e9c36e3b032f38bd42296a8495ac840b0625c097d9
Encrypted (hex) (block = 16)  :[b05d6aedf023f73b9e1e2d11f6f5137d, 971aea8c5cdd5b045e0960eb4408e0ee, 4635cccc2dfeec2c13a89bd400f659be, 82dc2329e9c36e3b032f38bd42296a84, 95ac840b0625c097d9]

------ AES GCM Decryption ------
Input (hex)                   :b05d6aedf023f73b9e1e2d11f6f5137d971aea8c5cdd5b045e0960eb4408e0ee4635cccc2dfeec2c13a89bd400f659be82dc2329e9c36e3b032f38bd42296a8495ac840b0625c097d9
Input (hex) (block = 16)      :[b05d6aedf023f73b9e1e2d11f6f5137d, 971aea8c5cdd5b045e0960eb4408e0ee, 4635cccc2dfeec2c13a89bd400f659be, 82dc2329e9c36e3b032f38bd42296a84, 95ac840b0625c097d9]
Key (hex)                     :ddc24663d104e1c2f81f11aef98156503dafdc435f81e3ac3d705015ebab095c
Decrypted (plain text)        :Hello World AES-GCM, Welcome to Cryptography!

3. AES Password-Based encryption and decryption.

For password-based encryption, we can use the Password-Based Cryptography Specification (PKCS), defined RFC 8018, to generate a key from a given password.

For PKCS inputs:

  • Password, you provide this.
  • Salt – At least 64 bits (8 bytes) random bytes.
  • Iteration Count – Recommend a minimum iteration count of 1,000.

What is salt and iteration count?

  • The salt produces a broad set of keys for a given password. For example, if the salt is 128 bits, there will be as many as 2^128 keys for each password. Therefore, it increases the difficulty of rainbow attacks. Furthermore, the rainbow table that attackers build for one user’s password became useless for another user.
  • The iteration count increasing the cost of producing keys from a password, therefore increasing difficulty and slow down the speed of attacks.

3.1 For the encrypted output, we prefix the 12 bytes IV and password salt to the ciphertext, because we need the same IV and password salt (for secret key) for decryption. Furthermore, we use Base64 encoder to encode the encrypted text into a string representation, so that we can send the encrypted text or ciphertext in string format (was byte array).

Is this ok if password salt is publicly known?
It is the same with IV, and it is ok for password salt to be publicly known, the only secret is the key, keeping it private and confidential.

EncryptorAesGcmPassword.java

package com.mkyong.crypto.encryptor;

import com.mkyong.crypto.utils.CryptoUtils;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * AES-GCM inputs - 12 bytes IV, need the same IV and secret keys for encryption and decryption.
 * <p>
 * The output consist of iv, password's salt, encrypted content and auth tag in the following format:
 * output = byte[] {i i i s s s c c c c c c ...}
 * <p>
 * i = IV bytes
 * s = Salt bytes
 * c = content bytes (encrypted content)
 */
public class EncryptorAesGcmPassword {

    private static final String ENCRYPT_ALGO = "AES/GCM/NoPadding";

    private static final int TAG_LENGTH_BIT = 128; // must be one of {128, 120, 112, 104, 96}
    private static final int IV_LENGTH_BYTE = 12;
    private static final int SALT_LENGTH_BYTE = 16;
    private static final Charset UTF_8 = StandardCharsets.UTF_8;

    // return a base64 encoded AES encrypted text
    public static String encrypt(byte[] pText, String password) throws Exception {

        // 16 bytes salt
        byte[] salt = CryptoUtils.getRandomNonce(SALT_LENGTH_BYTE);

        // GCM recommended 12 bytes iv?
        byte[] iv = CryptoUtils.getRandomNonce(IV_LENGTH_BYTE);

        // secret key from password
        SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.toCharArray(), salt);

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);

        // ASE-GCM needs GCMParameterSpec
        cipher.init(Cipher.ENCRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv));

        byte[] cipherText = cipher.doFinal(pText);

        // prefix IV and Salt to cipher text
        byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length)
                .put(iv)
                .put(salt)
                .put(cipherText)
                .array();

        // string representation, base64, send this string to other for decryption.
        return Base64.getEncoder().encodeToString(cipherTextWithIvSalt);

    }

    // we need the same password, salt and iv to decrypt it
    private static String decrypt(String cText, String password) throws Exception {

        byte[] decode = Base64.getDecoder().decode(cText.getBytes(UTF_8));

        // get back the iv and salt from the cipher text
        ByteBuffer bb = ByteBuffer.wrap(decode);

        byte[] iv = new byte[IV_LENGTH_BYTE];
        bb.get(iv);

        byte[] salt = new byte[SALT_LENGTH_BYTE];
        bb.get(salt);

        byte[] cipherText = new byte[bb.remaining()];
        bb.get(cipherText);

        // get back the aes key from the same password and salt
        SecretKey aesKeyFromPassword = CryptoUtils.getAESKeyFromPassword(password.toCharArray(), salt);

        Cipher cipher = Cipher.getInstance(ENCRYPT_ALGO);

        cipher.init(Cipher.DECRYPT_MODE, aesKeyFromPassword, new GCMParameterSpec(TAG_LENGTH_BIT, iv));

        byte[] plainText = cipher.doFinal(cipherText);

        return new String(plainText, UTF_8);

    }

    public static void main(String[] args) throws Exception {

        String OUTPUT_FORMAT = "%-30s:%s";
        String PASSWORD = "this is a password";
        String pText = "AES-GSM Password-Bases encryption!";

        String encryptedTextBase64 = EncryptorAesGcmPassword.encrypt(pText.getBytes(UTF_8), PASSWORD);

        System.out.println("\n------ AES GCM Password-based Encryption ------");
        System.out.println(String.format(OUTPUT_FORMAT, "Input (plain text)", pText));
        System.out.println(String.format(OUTPUT_FORMAT, "Encrypted (base64) ", encryptedTextBase64));

        System.out.println("\n------ AES GCM Password-based Decryption ------");
        System.out.println(String.format(OUTPUT_FORMAT, "Input (base64)", encryptedTextBase64));

        String decryptedText = EncryptorAesGcmPassword.decrypt(encryptedTextBase64, PASSWORD);
        System.out.println(String.format(OUTPUT_FORMAT, "Decrypted (plain text)", decryptedText));

    }

}

Output

Terminal

------ AES GCM Password-based Encryption ------
Input (plain text)            :AES-GSM Password-Bases encryption!
Encrypted (base64)            :KmrvjnMusJTQo/hB7T5BvlQpvi3bVbdjpZP51NT7I/enrIfSQuDfSK6iXgdPzvUP2IE54mwrKiyHqMkG8224lRZ9tXHcclmdh98I8b3B

------ AES GCM Password-based Decryption ------
Input (base64)                :KmrvjnMusJTQo/hB7T5BvlQpvi3bVbdjpZP51NT7I/enrIfSQuDfSK6iXgdPzvUP2IE54mwrKiyHqMkG8224lRZ9tXHcclmdh98I8b3B
Decrypted (plain text)        :AES-GSM Password-Bases encryption!

3.2 If password is not match, Java throws AEADBadTagException: Tag mismatch!


  // change the password to something else
  String decryptedText = EncryptorAesGcmPassword.decrypt(encryptedTextBase64, "other password");
  System.out.println(String.format(OUTPUT_FORMAT, "Decrypted (plain text)", decryptedText));

Output

Terminal

Exception in thread "main" javax.crypto.AEADBadTagException: Tag mismatch!
  at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:623)
  at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1118)
  at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1055)
  at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:855)
  at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
  at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2207)
  at com.mkyong.crypto.encryptor.EncryptorAesGcmPassword.decrypt(EncryptorAesGcmPassword.java:88)
  at com.mkyong.crypto.encryptor.EncryptorAesGcmPassword.main(EncryptorAesGcmPassword.java:109)

4. AES File encryption and decryption.

This example is an AES password-based file encryption. The ideas are the same, but we need some IO classes to work with the resources or files.

Here’s a text file, at the resources folder.

readme.txt

This is line 1.
This is line 2.
This is line 3.
This is line 4.
This is line 5.
This is line 9.
This is line 10.

4.1 This example is similar to 3.1 EncryptorAesGcmPassword.java, with some minor changes like return a byte[] instead of base64 encoded string.


  public static byte[] encrypt(byte[] pText, String password) throws Exception {

        //...

        // prefix IV and Salt to cipher text
        byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length + cipherText.length)
                .put(iv)
                .put(salt)
                .put(cipherText)
                .array();

        // it works, even if we save the based64 encoded string into a file.
        // return Base64.getEncoder().encodeToString(cipherTextWithIvSalt);

        // we save the byte[] into a file.
        return cipherTextWithIvSalt;

    }

Add encryptFile and decryptFile to work with the file.


    public static void encryptFile(String fromFile, String toFile, String password) throws Exception {

        // read a normal txt file
        byte[] fileContent = Files.readAllBytes(Paths.get(ClassLoader.getSystemResource(fromFile).toURI()));

        // encrypt with a password
        byte[] encryptedText = EncryptorAesGcmPasswordFile.encrypt(fileContent, password);

        // save a file
        Path path = Paths.get(toFile);

        Files.write(path, encryptedText);

    }

    public static byte[] decryptFile(String fromEncryptedFile, String password) throws Exception {

        // read a file
        byte[] fileContent = Files.readAllBytes(Paths.get(fromEncryptedFile));

        return EncryptorAesGcmPasswordFile.decrypt(fileContent, password);

    }

4.2 Read the above readme.txt file from the classpath, encrypt it, and the encrypted data to a new file c:\test\readme.encrypted.txt.


  String password = "password123";
  String fromFile = "readme.txt"; // from resources folder
  String toFile = "c:\\test\\readme.encrypted.txt";

  // encrypt file
  EncryptorAesGcmPasswordFile.encryptFile(fromFile, toFile, password);

Output

AES file encryption

4.3 Read the encrypted file, decrypt it, and print the output.


  String password = "password123";
  String toFile = "c:\\test\\readme.encrypted.txt";

  // decrypt file
  byte[] decryptedText = EncryptorAesGcmPasswordFile.decryptFile(toFile, password);
  String pText = new String(decryptedText, UTF_8);
  System.out.println(pText);

Output

Terminal

This is line 1.
This is line 2.
This is line 3.
This is line 4.
This is line 5.
This is line 9.
This is line 10.

P.S The AES image encryption is the same concept.

Download Source Code

$ git clone https://github.com/mkyong/core-java

$ cd java-crypto

Let me know if the article needs improvement. Thanks.

References

author image

mkyong

Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities. Read all published posts by

Comments

avatar
3000
newest oldest most voted
kingk
Guest
kingk

SHA1PRNG, there is a SeedGenerator which does various things depending on the configuration.

If java.security.egd or securerandom.source point to “file:/dev/random” or “file:/dev/urandom”, we will use NativeSeedGenerator, which calls super() which calls SeedGenerator.URLSeedGenerator(/dev/random). (A nested class within SeedGenerator.) The only things that changed in this bug was that urandom will also trigger use of this code path.

If those properties point to another URL that exists, we’ll initialize SeedGenerator.URLSeedGenerator(url). This is why “file:///dev/urandom”, “file:/./dev/random”, etc. will work.

SecureRandom.getInstanceStrong()

kingk
Guest
kingk

SecureRandom. GetInstanceStrong () will cause congestion
n SHA1PRNG, there is a SeedGenerator which does various things depending on the configuration.

If java.security.egd or securerandom.source point to “file:/dev/random” or “file:/dev/urandom”, we will use NativeSeedGenerator, which calls super() which calls SeedGenerator.URLSeedGenerator(/dev/random). (A nested class within SeedGenerator.) The only things that changed in this bug was that urandom will also trigger use of this code path.

If those properties point to another URL that exists, we’ll initialize SeedGenerator.URLSeedGenerator(url). This is why “file:///dev/urandom”, “file:/./dev/random”, etc. will work.

Vlad VALICA
Guest
Vlad VALICA

Thanks for this article!
One typo in
2. AES encryption and decryption.
The AES-GSM is the most widely used authenticated cipher.
That should be AES-GCM
The initialisation vector for GCM shall have 12bit length, you can remove the question mark in the code sample.
Thanks again for your explicit and clear example!

Michael Fehr
Guest
Michael Fehr

Very good article, thanks! Just one typo: “2.1 In Java, we use AES/CBC/PKCS5Padding to represent the AES-GCM algorithm.” I think it should be “2.1 In Java, we use AES/GCM/NoPadding to represent the AES-GCM algorithm.”