Appendix A: Java Code Sample: Auth Header Generation
CODE
private static final String AUTH_HEADER_SCHEME = "TrSvcAreaAuthHeader";
private static final int BUFFER_SIZE = 4 * 1024 * 1024;
private String buildAuthHeader() throws ThruTransportException {
logger.debug("[buildAuthHeader] Constructing Authorization header...");
try {
DateTime now = new DateTime(DateTimeZone.UTC);
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd-HH-mm-ss");
String date = formatter.print(now);
String authHeader = String.format("%s|%s|%s", "1.0" /* API Version */, SECRET_KEY, date);
String val = String.format("%s %s", AUTH_HEADER_SCHEME, encrypt(authHeader));
logger.debug("[buildAuthHeader] Authorization header constructed: %s", val);
return val;
} catch(Exception ex){
logger.error("[buildAuthHeader] Unable to construct Authorization header", ex);
System.out.print(ex.getMessage());
throw new ThruTransportException("[buildAuthHeader]" + ex.getMessage(), MFTErrorType.UNABLE_BUILD_AUTH_HEADER);
}
}
private String encrypt(String data) throws Exception {
logger.debug("[encrypt] Encrypting data: %s", data);
byte[] salt = generateSalt();
Cipher cipher = buildCipher(salt);
byte[] encrypted = cipher.doFinal(data.getBytes("UTF-16LE"));
byte[] result = new byte[salt.length + encrypted.length];
System.arraycopy(salt, 0, result, 0, salt.length);
System.arraycopy(encrypted, 0, result, salt.length, encrypted.length);
String base64String = Base64.encodeBytes(result, Base64.DONT_BREAK_LINES);
logger.debug("[encrypt] Data encrypted: %s", base64String);
return base64String;
}
private Cipher buildCipher(byte[] salt)
throws NoSuchAlgorithmException,
NoSuchPaddingException,
InvalidKeySpecException,
InvalidKeyException,
InvalidAlgorithmParameterException
{
logger.debug("[buildChiper] Configuring cipher for encryption");
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec pbeKeySpec = new PBEKeySpec(ENCRYPTION_KEY.toCharArray(), salt, 1000, 256);
Key secretKey = factory.generateSecret(pbeKeySpec);
byte[] keyBytes = new byte[16];
byte[] ivBytes = new byte[16];
System.arraycopy(secretKey.getEncoded(), 0, keyBytes, 0, 16);
System.arraycopy(secretKey.getEncoded(), 16, ivBytes, 0, 16);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
AlgorithmParameterSpec iv = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
return cipher;
}
private byte[] generateSalt() {
logger.debug("[generateSalt] Generating salt");
byte[] salt = new byte[8];
Random rand = new SecureRandom();
rand.nextBytes(salt);
return salt;
}