9.8. Encryption

9.8.1. Overview

Encryption is required for confidential information like personal data, passwords etc in the following cases.

  • Sending/receiving confidential information through a network medium like Internet
  • Storing confidential information in external resources like database, file etc
Spring Security also offers encryption related functions besides the major functions like “Authentication” and “Authorization”.
However, since functions offered by Spring Security are limited, the encryption methods which are not supported by Spring Security must be implemented independently.

The guideline explains following processes.

  • Encryption and decryption by common key encryption methods which use class offered by Spring Security
  • Generation of pseudo-random numbers which use class offered by Spring Security
  • Encryption and decryption by public key encryption method which use JCA (Java Cryptography Architecture)
  • Encryption and decryption by hybrid encryption method which use JCA

For details of Encryption function of Spring Security, refer Spring Security Reference -Spring Security Crypto Module-.

9.8.1.1. Encryption method

Encryption method is explained below.

9.8.1.1.1. Common key encryption method

It is a method which uses the same key during encryption and decryption.
Since the method shares a key used in decryption for the encryption, a different path to safely transfer the key to encryption side is required.

9.8.1.1.2. Public key encryption method

It is a method wherein encryption is performed by using a public key offered by decryption side and decryption is performed by using a secret key which is paired with the public key.
Secret key used while decrypting encrypted text is not published resulting in high security strength, however cost of encryption and decryption is likely to be high.

9.8.1.1.3. Hybrid encryption method

It is a method which combines merits of common key encryption method wherein processing cost is less and merits of public key encryption method wherein security strength is high due to easy management and distribution of key.
This method is used in SSL/TLS etc.

For example, in HTTPS communication, common key generated at the client side is sent after encrypting it with public key on the server side and common key is decrypted at the server by using secret key paired with public key. The subsequent communication is done by a common key encryption method which uses a shared common key.

This method consists of

  • Confidential information which is likely to be large in size is encrypted by a common key encryption method wherein the processing cost is less
  • A common key with smaller size wherein safe distribution is required is encrypted by using a public key encryption method with high security strength

Since common key used while decrypting confidential information is protected by secret key, security strength of public key encryption method is retained while achieving a high-speed encryption and decryption process than public key encryption method.

Process flow of hybrid encryption method from encryption to decryption is shown in the following figure..

Hybrid Encryption
  1. Sender generates a common key for encryption of plain text.
  2. Plain text is encrypted by common key generated by sender.
  3. Sender uses public key of receiving side to encrypt common key.
  4. Sender sends encrypted text along with encrypted common key.
  5. Receiving side decrypts encrypted common key by using secret key on receiving side.
  6. Receiving side decrypts encrypted text by decrypted common key

9.8.1.2. Encryption algorithm

Encryption algorithm is explained.

9.8.1.2.1. DES / 3DES

DES (Data Encryption Standard) is an algorithm standardised in USA as an algorithm for common encryption method. Currently, it is not recommended since key length is short at 56 bits.
3DES (triple DES) is an encryption algorithm which repeats DES while changing the key.

9.8.1.2.2. AES

AES (Advanced Encryption Standard) is an algorithm for common key encryption method. It is an encryption standard established subsequent to DES and is used as a current default standard for encryption.
Also, ECB (Electronic Codebook), CBC (Cipher Block Chaining) and OFB (Output Feedback) are provided as encryption mode wherein a message longer than the block length is encrypted. Of these, CBC is widely used.

Note

AES with GCM

GCM (Galois/Counter Mode) is an encryption mode generally accepted for feasible parallel processing and excellent processing efficiency as compared to CEC and can be used in AES.

9.8.1.2.3. RSA

RSA is an algorithm of public key encryption method. Ability of a computing machine impacts the algorithm since it is based on difficulty of prime numbers factoring. It requires adequate key length as indicated in “Issues of encryption algorithm in 2010”. At present, 2048 bits is used a standard length.

9.8.1.2.4. DSA / ECDSA

DSA (Digital Signature Algorithm) is a standard specification for digital signature. It is based on the difficulty of discrete logarithmic problem.
ECDSA (Elliptic Curve Digital Signature Algorithm ) is a variant of DSA which uses Elliptic curve photography. Elliptic curve photography offers an advantage of reducing key length which is necessary for maintaining security level.

9.8.1.3. Pseudo-random number (Generator)

Random numbers are used in the generation of a key.
In this case, if the value of a number generated at random can be predicted, encryption security can no longer be maintained. Hence, a random number which cannot be predicted easily (pseudo-random number) must be used.
It is a pseudo-random number generator which is used to generate a pseudo-random number.

9.8.1.4. javax.crypto.Cipher class

Cipher class offers encryption and decryption functions, and specifies a combination of encryption algorithms like AES or RSA, encryption modes like ECB or CBC and padding methods like PKCS1.

Encryption mode is a mechanism to encrypt messages longer than block length, as explained in AES.
Also, padding method is a method of storage when encryption target that does not meet the required block length is to be encrypted.

Java application specifies a combination in the <Encryption algorithm>/<Encryption mode>/<Padding method> or <Encryption algorithm> format. For example, AES/CBC/PKCS5Padding or RSA are used. For details, refer to JavaDoc of Cipher class.

9.8.1.5. Encryption function in Spring Security

Spring Security offers an encryption and decryption function which uses a common key encryption method.
Encryption algorithm is 256-bit AES using PKCS #5’s PBKDF2 (Password-Based Key Derivation Function #2).
Encryption mode is CBC and padding method is PKCS5Padding.

9.8.1.5.1. Components for encryption and decryption

Spring Security offers following interfaces as a function for encryption and decryption using common key encryption method.

  • org.springframework.security.crypto.encrypt.TextEncryptor (For text)
  • org.springframework.security.crypto.encrypt.BytesEncryptor (For byte array)

Also, following classes are offered as implementation classes for these interfaces and Cipher class is used internally.

  • org.springframework.security.crypto.encrypt.HexEncodingTextEncryptor (For text)
  • org.springframework.security.crypto.encrypt.AesBytesEncryptor (For byte array)

9.8.1.5.2. Components to generate random numbers

Spring Security offers following interfaces as functions to generate random numbers (key).

  • org.springframework.security.crypto.keygen.StringKeyGenerator (for text)
  • org.springframework.security.crypto.keygen.BytesKeyGenerator (for byte array)

Also, following classes are offered as implementation classes for these interfaces.

  • org.springframework.security.crypto.keygen.HexEncodingStringKeyGenerator (for text)
  • org.springframework.security.crypto.keygen.SecureRandomBytesKeyGenerator (for byte array. Generate a different key length by generateKey method and return)
  • org.springframework.security.crypto.keygen.SharedKeyGenerator (for byte array. Return same key length set by constructor, using generateKey method)

Note

Spring Security RSA

spring-security-rsa offers API for public key encryption method and hybrid encryption method which use RSA as an encryption algorithm. spring-security-rsa is currently not managed as official repository of Spring <https://github.com/spring-projects>_. Later, how to use the repository will be explained in the guideline after moving it under official repository of Spring.

spring-security-rsa offers 2 classes given below.

  • org.springframework.security.crypto.encrypt.RsaRawEncryptor

    A class that offers encryption and decryption functions which use public key encryption method.

  • org.springframework.security.crypto.encrypt.RsaSecretEncryptor

    A class that offers encryption and decryption functions which use hybrid encryption method.


9.8.2. How to use

An unlimited strength JCE jurisdiction policy file must be applied for handling key length 256 bits of AES in some Java products like Oracle.

Note

JCE jurisdiction policy file

Default encryption algorithm strength is restricted in some Java products due to relation with import regulations. If a more powerful algorithm is to be used, an unlimited strength JCE jurisdiction policy file must be obtained and installed in JDK/JRE. For details, refer Java Cryptography Architecture Oracle Providers Documentation.

Download destination for JCE jurisdiction policy file

9.8.2.1. Common key encryption method

A method is explained wherein AES is used as an encryption algorithm.

9.8.2.1.1. Encryption of character string

  • Encrypt text (string).

    public static String encryptText(
        String secret, String salt, String plainText) {
        TextEncryptor encryptor = Encryptors.text(secret, salt); // (1)
    
        return encryptor.encrypt(plainText); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#text method by specifying common key and salt, and generate instance of TextEncryptor class.
    Since initialization vector of generated instance is random, a varied result is returned at the time of encryption. It should be noted that CEC is used as an encryption mode.
    Common key and salt specified during encryption are also used at the time of decryption.
    (2)
    Encrypt plain text by using encrypt method.

    Note

    Regarding encryption results

    Return value of encrypt method (encryption results) return a different value for each execution, however, if key and salt are identical, decryption process results will be similar as well (can be correctly decrypted).


  • Fetch identical encryption results.

    This method is used in the processes such as searching the database etc.using encrypted results. However, whether to use the method must be reviewed considering possible reduction in the security strength.

    public static void encryptTextResult(
        String secret, String salt, String plainText) {
        TextEncryptor encryptor = Encryptors.queryableText(secret, salt); // (1)
        System.out.println(encryptor.encrypt(plainText)); // (2)
        System.out.println(encryptor.encrypt(plainText)); //
    }
    
    Sr.No. Description
    (1)
    When identical value must be fetched as encryption results, generate an instance of TextEncryptor class by using Encryptors#queryableText method.
    (2)
    The instance generated by Encryptors#queryableText method returns identical values as the encryption results for encrypt method.

  • Encrypt text (string) by using AES which uses GCM.

    AES using GCM can be used in Spring Security4.0.2 and subsequent versions. Processing efficiency is superior to CEC as explained in AES.

    public static String encryptTextByAesWithGcm(String secret, String salt, String plainText) {
        TextEncryptor aesTextEncryptor = Encryptors.delux(secret, salt); // (1)
    
        return aesTextEncryptor.encrypt(plainText); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#delux method by specifying common key and salt, and generate an instance of TextEncryptor class.
    Common key and salt specified during encryption are also used at the time of decryption.
    (2)
    Encrypt plain text by using encrypt method.

    Note

    Java support for AES which uses GCM

    AES using GCM can be used in Java SE8 and subsequent versions. For details, refer JDK 8 security enhancement.


9.8.2.1.2. Decryption of string

  • Decrypt encryption text of text (string).

    public static String decryptText(String secret, String salt, String cipherText) {
        TextEncryptor decryptor = Encryptors.text(secret, salt); // (1)
    
        return decryptor.decrypt(cipherText); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#text method by specifying common key and salt, and generate an instance of TextEncryptor class.
    Specify values used at the time of encryption as common key and salt.
    (2)
    Decrypt encrypted text by using decrypt method.

  • Decrypt encrypted text of text (string) by using AES which uses GCM.

    public static String decryptTextByAesWithGcm(String secret, String salt, String cipherText) {
        TextEncryptor aesTextEncryptor = Encryptors.delux(secret, salt); // (1)
    
        return aesTextEncryptor.decrypt(cipherText); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#delux method by specifying common key and salt, and generate an instance of TextEncryptor class.
    Specify values at the time of encryption as common key and salt.
    (2)
    Decrypt encrypted text by using decrypt method.

9.8.2.1.3. Encryption of byte array

  • Encrypt byte array.

    public static byte[] encryptBytes(String secret, String salt, byte[] plainBytes) {
        BytesEncryptor encryptor = Encryptors.standard(secret, salt); // (1)
    
        return encryptor.encrypt(plainBytes); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#standard method by specifying common key and salt, and generate an instance of BytesEncryptor class.
    Common key and salt specified during encryption are also used at the time of decryption.
    (2)
    Encrypt plain text of byte array by using encrypt method.

  • Encrypt byte array by using AES which uses GCM.

    public static byte[] encryptBytesByAesWithGcm(String secret, String salt, byte[] plainBytes) {
        BytesEncryptor aesBytesEncryptor = Encryptors.stronger(secret, salt); // (1)
    
        return aesBytesEncryptor.encrypt(plainBytes); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#stronger method by specifying common key and salt, and generate an instance of BytesEncryptor class.
    Common key and salt specified during encryption are also used at the time of decryption.
    (2)
    Encrypt plain text of byte array by using encrypt method.

9.8.2.1.4. Decryption of byte array

Decrypt encrypted text of byte array.

public static byte[] decryptBytes(String secret, String salt, byte[] cipherBytes) {
    BytesEncryptor decryptor = Encryptors.standard(secret, salt); // (1)

    return decryptor.decrypt(cipherBytes); // (2)
}
Sr. No. Description
(1)
Call Encryptors#standard method by specifying common key and salt, and generate an instance of BytesEncryptor class.
Specify values used at the time of encryption as common key and salt.
(2)
Decrypt encrypted text of byte array by using decrypt method.

  • Decrypt byte array using AES which use GCM.

    public static byte[] decryptBytesByAesWithGcm(String secret, String salt, byte[] cipherBytes) {
        BytesEncryptor aesBytesEncryptor = Encryptors.stronger(secret, salt); // (1)
    
        return aesBytesEncryptor.decrypt(cipherBytes); // (2)
    }
    
    Sr. No. Description
    (1)
    Call Encryptors#stronger method by specifying common key and salt, and generate an instance of BytesEncryptor class.
    Specify values used at the time of encryption as common key and salt.
    (2)
    Decrypt encrypted text of byte array by using decrypt method.

9.8.2.2. Public key encryption method

Since functions related to public key encryption method are not offered by Spring Security, a method which uses JCA and OpenSSL is explained using a sample code.

9.8.2.2.1. Preliminary preparation (Generation of key pairs using JCA)

  • Generate key pairs (a combination of public key / secret key) using JCA, perform encryption and decryption process by using public key and secret key respectively.

    public void generateKeysByJCA() {
        try {
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); // (1)
            generator.initialize(2048); // (2)
            KeyPair keyPair = generator.generateKeyPair(); // (3)
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
    
            byte[] cipherBytes = encryptByPublicKey("Hello World!", publicKey);  // (4)
            String plainText = decryptByPrivateKey(cipherBytes, privateKey); // (5)
            System.out.println(plainText);
        } catch (NoSuchAlgorithmException e) {
            throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
        }
    }
    
    Sr. No. Description
    (1)
    Specify RSA algorithm and generate an instance of KeyPairGenerator class.
    (2)
    Specify 2048 bits as a key length.
    (3)
    Generate key pairs.
    (4)
    Use public key and perform encryption process. Processing details will be described later.
    (5)
    Use secret key and perform decryption process. Processing details will be described later.

    Note

    When the encrypted data is to be handled as string

    When encrypted data is to be handled as string like in external system linkage etc, Base64 encoding can be listed as one of the measures. java.util.Base64 of Java standard is used in case of subsequent versions of Java SE8. In the earlier versions, org.springframework.security.crypto.codec.Base64 of Spring Security is used.

    A method used for Base64 encoding and decoding is explained using java.util.Base64 of Java standard.

    • Base64 encoding
    // omitted
    byte[] cipherBytes = encryptByPublicKey("Hello World!", publicKey);  // Encryption process
    String cipherString = Base64.getEncoder().encodeToString(cipherBytes);  // Convert encrypted text of byte array to string
    // omitted
    
    • Base64 decoding
    // omitted
    byte[] cipherBytes = Base64.getDecoder().decode(cipherString); // Convert encrypted text of string to byte array
    String plainText = decryptByPrivateKey(cipherBytes, privateKey); // Decryption process
    // omitted
    

9.8.2.2.2. Encryption

  • Use public key and encrypt character string.

    public byte[] encryptByPublicKey(String plainText, PublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // (1)
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);                       // (2)
            return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); //
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
        } catch (InvalidKeyException |
                 IllegalBlockSizeException |
                 BadPaddingException e) {
            throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
        }
    }
    
    Sr.No. Description
    (1)
    Specify encryption algorithm, encryption mode and padding method, and generate an instance of Cipher class.
    (2)
    Execute encryption process.

9.8.2.2.3. Decryption

  • Use secret key and decrypt byte array.

    public String decryptByPrivateKey(byte[] cipherBytes, PrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // (1)
            cipher.init(Cipher.DECRYPT_MODE, privateKey);           // (2)
            byte[] plainBytes = cipher.doFinal(cipherBytes); //
            return new String(plainBytes, StandardCharsets.UTF_8);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
        } catch (InvalidKeyException |
                 IllegalBlockSizeException |
                 BadPaddingException e) {
            throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
        }
    }
    
    Sr. No. Description
    (1)
    Specify encryption algorithm, encryption mode and padding method, and generate an instance of Cipher class.
    (2)
    Execute decryption process.

9.8.2.2.4. OpenSSL

If Cipher is identical, a different method can be used for encryption and decryption for public key encryption method.
Here, key pairs are created in advance by using OpenSSL and encryption is performed by JCA, by using this public key. Hence, a method wherein decryption process is performed by OpenSSL, by using the secret key is explained.

Note

OpenSSL

The software must be installed for creating key pairs by OpenSSL. It can be downloaded from the following site.

Download destination for OpenSSL


  • Create key pairs by OpenSSL as a preliminary preparation.

    $ openssl genrsa -out private.pem 2048  # (1)
    
    $ openssl pkcs8 -topk8 -nocrypt -in private.pem -out private.pk8 -outform DER  # (2)
    
    $ openssl rsa -pubout -in private.pem -out public.der -outform DER  # (3)
    
    Sr. No. Description
    (1)
    Generate secret key of 2048 bits (DER format) by OpenSSL..
    (2)
    Convert secret key to PKCS#8 format for reading it from Java application.
    (3)
    Generate public key (DER format) from secret key.

  • Read public key created by OpenSSL in the application and perform encryption process by using public key that has been read.

    public void useOpenSSLDecryption() {
        try {
            KeySpec publicKeySpec = new X509EncodedKeySpec(
                    Files.readAllBytes(Paths.get("public.der"))); // (1)
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); // (2)
    
            byte[] cipherBytes = encryptByPublicKey("Hello World!", publicKey); // (3)
    
            Files.write(Paths.get("encryptedByJCA.txt"), cipherBytes);
            System.out.println("Please execute the following command:");
            System.out
                    .println("openssl rsautl -decrypt -inkey hoge.pem -in encryptedByJCA.txt");
        } catch (IOException e) {
            throw new SystemException("e.xx.xx.9001", "input/output error.", e);
        } catch (NoSuchAlgorithmException e) {
            throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
        } catch (InvalidKeySpecException e) {
            throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
        }
    }
    
    Sr.No. Description
    (1)
    Read binary data from public key file.
    (2)
    Generate an instance of PublicKey class from binary data.
    (3)
    Perform encryption process by using public key.

  • Check that details encrypted by JCA can be decrypted by OpenSSL.

    $ openssl rsautl -decrypt -inkey private.pem -in encryptedByJCA.txt  # (1)
    
    Sr. No. Description
    (1)
    Decrypt by OpenSSL by using a secret key.

Further, a method wherein encryption and decryption are performed by OpenSSL and JCA respectively using key pairs created by OpenSSL is explained.
  • Perform encryption process by using OpenSSL commands.

    $ echo Hello | openssl rsautl -encrypt -keyform DER -pubin -inkey public.der -out encryptedByOpenSSL.txt  # (1)
    
    Sr. No. Description
    (1)
    Encrypt by OpenSSL by using a public key.

  • Read secret key created by OpenSSL in the application and perform decryption process by using a secret key that has been read.

    public void useOpenSSLEncryption() {
        try {
            KeySpec privateKeySpec = new PKCS8EncodedKeySpec(
                    Files.readAllBytes(Paths.get("private.pk8"))); // (1)
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec); // (2)
    
            String plainText = decryptByPrivateKey(
                   Files.readAllBytes(Paths.get("encryptedByOpenSSL.txt")),
                   privateKey); // (3)
            System.out.println(plainText);
        } catch (IOException e) {
            throw new SystemException("e.xx.xx.9001", "input/output error.", e);
        } catch (NoSuchAlgorithmException e) {
            throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
        } catch (InvalidKeySpecException e) {
            throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
        }
    }
    
    Sr. No. Description
    (1)
    Read binary data from secret key file of PKCS #8 format and generate an instance of PKCS8EncodedKeySpec class.
    (2)
    Generate an instance of PrivateKey class from KeyFactory class.
    (3)
    Perform decryption process by using a secret key.

9.8.2.3. Hybrid encryption method

Similar to public key encryption method, since functions related to hybrid encryption methods are not offered by Spring Security, it is explained using a sample code.
The sample code refers to RsaSecretEncryptor class of spring-security-rsa.

9.8.2.3.1. Encryption

public byte[] encrypt(byte[] plainBytes, PublicKey publicKey, String salt) {
    byte[] random = KeyGenerators.secureRandom(32).generateKey(); // (1)
    BytesEncryptor aes = Encryptors.standard(
            new String(Hex.encode(random)), salt); // (2)

    try (ByteArrayOutputStream result = new ByteArrayOutputStream()) {
        final Cipher cipher = Cipher.getInstance("RSA"); // (3)
        cipher.init(Cipher.ENCRYPT_MODE, publicKey); // (4)
        byte[] secret = cipher.doFinal(random); // (5)

        byte[] data = new byte[2]; // (6)
        data[0] = (byte) ((secret.length >> 8) & 0xFF); //
        data[1] = (byte) (secret.length & 0xFF); //
        result.write(data); //

        result.write(secret); // (7)
        result.write(aes.encrypt(plainBytes)); // (8)

        return result.toByteArray(); // (9)
    } catch (IOException e) {
        throw new SystemException("e.xx.xx.9001", "input/output error.", e);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
    } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
    }
}
Sr. No. Description
(1)
Call KeyGenerators#secureRandom method by specifyinh 32 bytes as a key length and generate an instance of BytesKeyGenerator class.
Call BytesKeyGenerator#generateKey method and generate a common key.
For details, refer to Random number generation.
(2)
Specify generated common key and salt, and generate an instance of BytesEncryptor class.
(3)
specify RSA as an encryption algorithm and generate an instance of Cipher class.
(4)
Specify encryption mode constant and public key, and initialise an instance of Cipher class.
(5)
Execute encryption process of common key. The encryption is performed by using public key encryption process.
(6)
Store length of encrypted common key in encrypted text of byte array. Length of stored common key is used at the time of decryption.
(7)
Store encrypted common key in encrypted text of byte array.
(8)
Encrypt plain text and store in encrypted text of byte array. The encryption is performed by using common key encryption process.
(9)
Return encrypted text of byte array.

9.8.2.3.2. Decryption

public byte[] decrypt(byte[] cipherBytes, PrivateKey privateKey, String salt) {

    try (ByteArrayInputStream input = new ByteArrayInputStream(cipherBytes);
            ByteArrayOutputStream output = new ByteArrayOutputStream()) {
        byte[] b = new byte[2]; // (1)
        input.read(b); //
        int length = ((b[0] & 0xFF) << 8) | (b[1] & 0xFF); //

        byte[] random = new byte[length]; // (2)
        input.read(random); //
        final Cipher cipher = Cipher.getInstance("RSA"); // (3)
        cipher.init(Cipher.DECRYPT_MODE, privateKey); // (4)
        String secret = new String(Hex.encode(cipher.doFinal(random))); // (5)
        byte[] buffer = new byte[cipherBytes.length - random.length - 2]; // (6)
        input.read(buffer); //
        BytesEncryptor aes = Encryptors.standard(secret, salt); // (7)
        output.write(aes.decrypt(buffer)); // (8)

        return output.toByteArray(); // (9)
    } catch (IOException e) {
        throw new SystemException("e.xx.xx.9001", "input/output error.", e);
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        throw new SystemException("e.xx.xx.9002", "No Such setting error.", e);
    } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        throw new SystemException("e.xx.xx.9003", "Invalid setting error.", e);
    }
}
Sr. No. Description
(1)
Fetch length of encrypted common key.
(2)
Fetch encrypted common key.
(3)
Specify RSA as an encryption algorithm and generate an instance of Cipher class.
(4)
Specify decryption mode constant and secret key, and initialise an instance of Cipher class.
(5)
Execute decryption process of common key. Decryption is performed by using public key encryption process.
(6)
Fetch decryption target.
(7)
Specify decrypted common key and salt, and generate an instance of BytesEncryptor class.
(8)
Execute decryption process. Decryption is performed by using common key encryption process.
(9)
Return plain text of decrypted byte array.

9.8.2.4. Random number generation

9.8.2.4.1. Generation of string type pseudo-random number

public static void createStringKey() {
    StringKeyGenerator generator = KeyGenerators.string(); // (1)
    System.out.println(generator.generateKey()); // (2)
    System.out.println(generator.generateKey()); //
}
Sr. No. Description
(1)
Generate an instance of key (pseudo-random number) generator StringKeyGenerator class.
If key is generated by this generator, a different value is obtained for each instance.

Key length cannot be specified, a key of length 8 byte is always generated.
(2)
Generate a key (pseudo-random number) by using generateKey method.

9.8.2.4.2. Generation of byte array type pseudo-randon number

  • Generate a different key.

    public static void createDifferentBytesKey() {
        BytesKeyGenerator generator = KeyGenerators.secureRandom(); // (1)
        System.out.println(Arrays.toString(generator.generateKey())); // (2)
        System.out.println(Arrays.toString(generator.generateKey())); //
    }
    
    Sr. No. Description
    (1)
    Call KeyGenerators#secureRandom method and generate an instance of key (pseudo-random number) generator BytesKeyGenerator class.
    If key is generated by this generator, a different value is obtained for each instance.

    When key length is not specified, a key of length - 8 bytes is generated by default.
    (2)
    Generate a key by using generateKey method.

  • Generate identical key.

    public static void createSameBytesKey() {
        BytesKeyGenerator generator = KeyGenerators.shared(32); // (1)
        System.out.println(Arrays.toString(generator.generateKey())); // (2)
        System.out.println(Arrays.toString(generator.generateKey())); //
    }
    
    Sr. No. Description
    (1)
    Specify 32 bytes as key length, call KeyGenerators#shared method and generate an instance of key (pseudo-random number) generator BytesKeyGenerator class.
    If key is generated by this generator, same value is obtained for each instance.

    Specifying key length is mandatory.
    (2)
    Generate key by using generateKey method.