package com.aplos.hermes.client.examples; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import com.menlolabs.gear.util.Functions; public class DecryptToken { /** * Decrypt a token using a private key file * @param encryptedToken * @param privateKey * @return Token decrypted using the given private key file * @throws IOException * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws NoSuchPaddingException * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public String decryptToken(String encryptedToken, File privateKeyFile) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { String privateKey = readTextFile(privateKeyFile); byte[] key = fromBase64(privateKey); KeyFactory kf = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key); PrivateKey k = kf.generatePrivate(spec); final Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); cipher.init(Cipher.DECRYPT_MODE, k); byte[] decryptedBytes = cipher.doFinal(fromBase64(encryptedToken)); return new String(decryptedBytes, "UTF-8"); } /** * Decode the given string using a Base64 decoder * @param encoded * @return Byte array decoded from the given base64 string * @throws IOException */ private byte[] fromBase64(String encoded) throws IOException { /* * We are using an Aplos class here. Other options are Apache Commons and Java 8 Base64. */ return Functions.fromBase64(encoded); } /** * Reads the file specified, returning the text as a String. * @param is the stream to read * @return String representation of the file data * @throws IOException if an error occurs while reading. */ public static String readTextFile(File f) throws IOException { FileInputStream is = null; ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { is = new FileInputStream(f); int l_numRead = 0; byte[] buffer = new byte[32768]; while ((l_numRead = is.read(buffer)) != -1) { bos.write(buffer, 0, l_numRead); } bos.flush(); bos.close(); is.close(); } finally { is.close(); } return bos.toString("UTF-8"); } }