How do I generate random string?

package org.kodejava.security;

import java.security.SecureRandom;
import java.util.Random;

public class RandomString {
    public static final String SOURCES =
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";

    public static void main(String[] args) {
        RandomString rs = new RandomString();
        System.out.println(rs.generateString(new Random(), SOURCES, 10));
        System.out.println(rs.generateString(new Random(), SOURCES, 10));
        System.out.println(rs.generateString(new SecureRandom(), SOURCES, 15));
        System.out.println(rs.generateString(new SecureRandom(), SOURCES, 15));
    }

    /**
     * Generate a random string.
     *
     * @param random     the random number generator.
     * @param characters the characters for generating string.
     * @param length     the length of the generated string.
     */
    public String generateString(Random random, String characters, int length) {
        char[] text = new char[length];
        for (int i = 0; i < length; i++) {
            text[i] = characters.charAt(random.nextInt(characters.length()));
        }
        return new String(text);
    }
}

Example string produced by the code snippets are:

bJGjSgoy7G
SoeTjBy83s
IolJZtkttJixAVY
ZOvQnICNcwcCdJ8

How to verify digital signature of a signed data?

In this example we will learn how to verify the digital signature of the previously signed data. To sign the data you can see the previous example on this post How to create a digital signature and sign data?.

Here the code snippet:

package org.kodejava.security;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;

public class VerifyDigitalSignature {
    public static void main(String[] args) {
        try {
            byte[] publicKeyEncoded = Files.readAllBytes(Paths.get("publickey"));
            byte[] digitalSignature = Files.readAllBytes(Paths.get("signature"));

            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyEncoded);
            KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");

            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
            Signature signature = Signature.getInstance("SHA1withDSA", "SUN");
            signature.initVerify(publicKey);

            byte[] bytes = Files.readAllBytes(Paths.get("README.md"));
            signature.update(bytes);

            boolean verified = signature.verify(digitalSignature);
            if (verified) {
                System.out.println("Data verified.");
            } else {
                System.out.println("Cannot verify data.");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

How to create a digital signature and sign data?

In the following code snippet you will learn how to generate a digital signature to sign a data or file. To create a signature we will need a key pair of public and private key. But for the signing process we’ll only use the private key, while the public key will be used to verify the signature.

To create a digital signature we need an instance of java.security.Signature. To get one we can call the Signature.getInstance() method and pass the algorithm and the provider arguments. In this code snippet we’ll use SHA1withDSA and SUN for the algorithm and provider.

But before we can use the Signature object we have to initialize it first with a PrivateKey. You can also see how to get a private key in the code snippet below. To initialize call the Signature‘s initSign() method.

And finally to generate the digital signature we need to update the Signature using the data that we are going to sign. To do this we read the file into byte[] using the helps of Files.readAllBytes() and supply the bytes into the Signature object using the update() method. To get the signature we call the sign() method which will return us a byte array of the signature.

And here is the complete code snippet:

package org.kodejava.security;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;

public class GenerateDigitalSignature {
    public static void main(String[] args) {
        try {
            // Get instance and initialize a KeyPairGenerator object.
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);

            // Get a PrivateKey from the generated key pair.
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();

            // Get an instance of Signature object and initialize it.
            Signature signature = Signature.getInstance("SHA1withDSA", "SUN");
            signature.initSign(privateKey);

            // Supply the data to be signed to the Signature object
            // using the update() method and generate the digital
            // signature.
            byte[] bytes = Files.readAllBytes(Paths.get("README.md"));
            signature.update(bytes);
            byte[] digitalSignature = signature.sign();

            // Save digital signature and the public key to a file.
            Files.write(Paths.get("signature"), digitalSignature);
            Files.write(Paths.get("publickey"), keyPair.getPublic().getEncoded());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

On the next examples we are going to verify the digital signature. To verify the digital signature is to make sure that the data was sent by the original creator without any modification. To verify we’ll need the digital signature and the public key of the key pair. To get these in the code snippet above we have saved both the digital signature and the public key to files.

How do I generate public and private keys?

The code snippet below show you how to use the JDK Security API to generate public and private keys. A private key can be used to sign a document and the public key is used to verify that the signature of the document is valid.

The API we used to generate the key pairs is in the java.security package. That’s mean we have to import this package into our code. The class for generating the key pairs is KeyPairGenerator. To get an instance of this class we have to call the getInstance() methods by providing two parameters. The first parameter is algorithm and the second parameter is the provider.

After obtaining an instance of the key generator, we have to initialize it. The initialize() method takes two parameters, the key size and a source of randomness. We set the key size to 1024 and pass and instance of SecureRandom.

Finally, to generate the key pairs we call the generateKeyPair() method of the KeyPairGenerator class. This will return a KeyPair object from where we can get the PrivateKey and PublicKey by calling the getPrivate() and getPublic() method.

Let’s see the code snippet below:

package org.kodejava.security;

import java.security.*;
import java.util.Base64;

public class GenerateKeyPairDemo {
    public static void main(String[] args) {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");

            // Initialize KeyPairGenerator.
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);

            // Generate Key Pairs, a private key and a public key.
            KeyPair keyPair = keyGen.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            Base64.Encoder encoder = Base64.getEncoder();
            System.out.println("privateKey: " + encoder.encodeToString(privateKey.getEncoded()));
            System.out.println("publicKey: " + encoder.encodeToString(publicKey.getEncoded()));
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            e.printStackTrace();
        }
    }
}

How do I get cryptographic security providers?

package org.kodejava.security;

import java.security.Provider;
import java.security.Security;
import java.util.Set;
import java.util.HashSet;

public class SecurityProvider {
    public static void main(String[] args) {
        // Create a set so that we can have a unique results.
        Set<String> results = new HashSet<>();

        // Returns an array containing all the installed providers.
        Provider[] providers = Security.getProviders();

        for (Provider provider : providers) {

            // Get provider's property keys
            Set<Object> keys = provider.keySet();
            for (Object key : keys) {
                String data = (String) key;
                data = data.split(" ")[0];

                // Service type started by the "Alg.Alias" string
                if (data.startsWith("Alg.Alias")) {
                    data = data.substring(10);
                }

                data = data.substring(0, data.indexOf('.'));
                results.add(data);
            }
        }

        for (Object object : results) {
            System.out.println("Service Type = " + object);
        }
    }
}

The example result of our code:

Service Type = Policy
Service Type = Configuration
Service Type = AlgorithmParameterGenerator
Service Type = TransformService
Service Type = CertificateFactory
Service Type = KeyInfoFactory
Service Type = CertPathBuilder
Service Type = MessageDigest
Service Type = KeyAgreement
Service Type = SecretKeyFactory
Service Type = KeyGenerator
Service Type = KeyFactory
Service Type = XMLSignatureFactory
Service Type = SaslServerFactory
Service Type = TerminalFactory
Service Type = SecureRandom
Service Type = SaslClientFactory
Service Type = KeyPairGenerator
Service Type = SSLContext
Service Type = KeyStore
Service Type = Mac
Service Type = Provider
Service Type = KeyManagerFactory
Service Type = CertPathValidator
Service Type = Signature
Service Type = TrustManagerFactory
Service Type = Cipher
Service Type = CertStore
Service Type = GssApiMechanism
Service Type = AlgorithmParameters