Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
StreamingKeyExample.java
package com.p6r.example13;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
public class StreamingKeyExampleForDisplay {
public StreamingKeyExampleForDisplay() {
}
public static void main(String[] args) {
Cipher encryptCipher = null;
// -> a real production program would use more dynamic buffers, we use these to make the example simple
byte[] cipherText1 = null; // could write the encrypted result to a file block by block
byte[] cipherText2 = null; // as it is producted. But we also want to show how to stream
byte[] cipherText3 = null; // decrypt it.
byte[] cipherText4 = null;
byte[] clearText1 = null; // could write the decrypted result to a file block by block
byte[] clearText2 = null; // as it is producted. But we also want to show how to stream
byte[] clearText3 = null; // decrypt it.
byte[] clearText4 = null;
try {
// [A] Get the P6R PKCS#11 security provider keytstore
// -> "12345678" is the keystore's password (i.e., the PKCS#11 token's PIN)
// -> "SunPKCS11-P6RPKCS11" defines the security provider
KeyStore ks = KeyStore.getInstance("PKCS11", "SunPKCS11-P6RPKCS11");
ks.load(null, "12345678".toCharArray());
// [B] Generate the symmetric key and store it into a PKCS#11 keystore
generateSymmetricKey(ks);
System.out.println("\nSearch for new AES key:\n");
Key secretKey = ks.getKey("example13_symmetric_aes_128_key", null);
if (secretKey != null) {
System.out.println("Key with alias 'example13_symmetric_aes_key' found: " + secretKey.toString());
// use a simple initialization vector
byte[] iv = new byte[16];
for (int i = 0; i < iv.length; i++) iv[i] = 0x03;
// Stream a large amount of data from a file or a socket into the Cipher
// Here we will just fake the data to keep the example simple
byte[] data = new byte[20];
if (null != (encryptCipher = encryptStart(secretKey, iv, "AES/CBC/NoPadding"))) {
System.out.println("\n\nStart streaming encryption");
for (int i = 0; i < data.length; i++) data[i] = (byte) i;
cipherText1 = encryptCipher.update(data);
System.out.println("First block to encrypt: ");
for (int i = 0; i < data.length; i++) System.out.print(data[i]);
for (int i = 0; i < data.length; i++) data[i] = (byte) (i + 2);
cipherText2 = encryptCipher.update(data);
System.out.println("\nSecond block to encrypt: ");
for (int i = 0; i < data.length; i++) System.out.print(data[i]);
for (int i = 0; i < data.length; i++) data[i] = (byte) (i + 3);
cipherText3 = encryptCipher.update(data);
System.out.println("\nThird block to encrypt: ");
for (int i = 0; i < data.length; i++) System.out.print(data[i]);
// -> since we are using a cipher that does not pad for use we have to make sure input data is a multiple of 16 (AES block size)
byte[] pad = new byte[4];
pad[0] = 0x01; pad[1] = 0x02; pad[2] = 0x03; pad[3] = 0x04;
cipherText4 = encryptCipher.doFinal(pad);
System.out.println("\nLast block to encrypt: ");
for (int i = 0; i < pad.length; i++) System.out.print(pad[i]);
}
if (null != (encryptCipher = decryptStart(secretKey, iv, "AES/CBC/NoPadding"))) {
System.out.println("\n\nStart streaming decryption to show we can properly undo the encryption");
clearText1 = encryptCipher.update(cipherText1);
System.out.println("Decrypted first block: ");
for (int i = 0; i < clearText1.length; i++) System.out.print(clearText1[i]);
clearText2 = encryptCipher.update(cipherText2);
System.out.println("\nDecrypted second block: ");
for (int i = 0; i < clearText2.length; i++) System.out.print(clearText2[i]);
clearText3 = encryptCipher.update(cipherText3);
System.out.println("\nDecrypted third block: ");
for (int i = 0; i < clearText3.length; i++) System.out.print(clearText3[i]);
clearText4 = encryptCipher.doFinal(cipherText4);
System.out.println("\nDecrypted last block: ");
for (int i = 0; i < clearText4.length; i++) System.out.print(clearText4[i]);
}
} else System.out.println("Key with alias 'example13_symmetric_aes_key' not found\n");
} catch (Exception e) {
e.printStackTrace();
}
}
private static Cipher encryptStart(Key secretKey, byte[] iv, String handling) {
Cipher encryptCipher = null;
try {
// with no security provider do the encrypt locally, in case KMIP server does not support encryption
// Cipher encryptCipher = Cipher.getInstance(handling);
// with a security provider do the encrypt on the remote server
encryptCipher = Cipher.getInstance(handling, "SunPKCS11-P6RPKCS11");
IvParameterSpec IV = new IvParameterSpec(iv);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, IV);
} catch (Exception e) {
e.printStackTrace();
}
return encryptCipher;
}
private static Cipher decryptStart(Key secretKey, byte[] iv, String handling) {
Cipher encryptCipher = null;
try {
// with no security provider do the encrypt locally, in case KMIP server does not support encryption
// Cipher encryptCipher = Cipher.getInstance(handling);
// with a security provider do the encrypt on the remote server
encryptCipher = Cipher.getInstance(handling, "SunPKCS11-P6RPKCS11");
IvParameterSpec IV = new IvParameterSpec(iv);
encryptCipher.init(Cipher.DECRYPT_MODE, secretKey, IV);
} catch (Exception e) {
e.printStackTrace();
}
return encryptCipher;
}
private static void generateSymmetricKey(KeyStore ks) throws NoSuchAlgorithmException, NoSuchProviderException, KeyStoreException {
KeyGenerator keyGen = KeyGenerator.getInstance("AES", "SunPKCS11-P6RPKCS11");
keyGen.init(128);
Key key = keyGen.generateKey();
System.out.println("Successfully created symmetric key: " + key.getAlgorithm() + "\n");
// replace an older key
if (ks.containsAlias("example13_symmetric_aes_128_key")) ks.deleteEntry("example13_symmetric_aes_128_key");
ks.setKeyEntry("example13_symmetric_aes_128_key", key, null, null);
}
}