/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.dreikraft.axbo.crypto;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
*
* @author jan_solo
*/
public class CryptoUtil
{
public static final Log log = LogFactory.getLog(CryptoUtil.class);
public static final String RSA_ALGORITHM = "RSA";
public static final String AES_ALGORITHM = "AES";
private static final int BUF_SIZE = 1024;
public enum KeyType
{
PRIVATE, PUBLIC
};
public static Key getPublicRSAKey(final String fileName) throws
CryptoException
{
try
{
// create the RSA keys from keySpec
final KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
return keyFactory.generatePublic(
new X509EncodedKeySpec(readKey(fileName)));
}
catch (InvalidKeySpecException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static Key getPrivateRSAKey(final String fileName) throws
CryptoException
{
try
{
// create the RSA keys from keySpec
final KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
return keyFactory.generatePrivate(
new PKCS8EncodedKeySpec(readKey(fileName)));
}
catch (InvalidKeySpecException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static Key generateAESKey() throws CryptoException
{
try
{
KeyGenerator keyGen = KeyGenerator.getInstance(AES_ALGORITHM);
keyGen.init(128);
return keyGen.generateKey();
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static byte[] wrapKey(final Key key, final String keyFile)
throws CryptoException
{
try
{
final Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);
rsaCipher.init(Cipher.WRAP_MODE, getPrivateRSAKey(keyFile));
return rsaCipher.wrap(key);
}
catch (IllegalBlockSizeException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (CryptoException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static Key unwrapKey(final InputStream in, final String keyFile)
throws CryptoException
{
try
{
final Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);
rsaCipher.init(Cipher.UNWRAP_MODE, getPublicRSAKey(keyFile));
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final byte[] buf = new byte[BUF_SIZE];
int avail;
while ((avail = in.read(buf)) != -1)
{
out.write(buf, 0, avail);
}
return rsaCipher.unwrap(out.toByteArray(), AES_ALGORITHM,
Cipher.SECRET_KEY);
}
catch (IOException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (CryptoException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static byte[] readKey(final String fileName) throws CryptoException
{
BufferedInputStream keyIn = null;
ByteArrayOutputStream keyOut = null;
try
{
keyIn = new BufferedInputStream(
CryptoUtil.class.getResourceAsStream(fileName), BUF_SIZE);
keyOut = new ByteArrayOutputStream();
final byte[] keyBuffer = new byte[BUF_SIZE];
int available;
while ((available = keyIn.read(keyBuffer)) != -1)
{
keyOut.write(keyBuffer, 0, available);
}
keyOut.flush();
return keyOut.toByteArray();
}
catch (IOException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
finally
{
try
{
if (keyIn != null)
{
keyIn.close();
}
if (keyOut != null)
{
keyOut.close();
}
}
catch (IOException ex)
{
log.warn(ex.getMessage(), ex);
}
}
}
public static InputStream encryptInput(final InputStream in, final Key key)
throws CryptoException
{
try
{
Cipher aesCipher = Cipher.getInstance(AES_ALGORITHM);
aesCipher.init(Cipher.ENCRYPT_MODE, key);
InputStream cin = new CipherInputStream(in, aesCipher);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[BUF_SIZE];
int avail;
while ((avail = cin.read(buf)) != -1)
{
out.write(buf, 0, avail);
}
return new ByteArrayInputStream(out.toByteArray());
}
catch (IOException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static InputStream decryptInput(final InputStream in, final Key key)
throws CryptoException
{
try
{
Cipher aesCipher = Cipher.getInstance(AES_ALGORITHM);
aesCipher.init(Cipher.DECRYPT_MODE, key);
InputStream cin = new CipherInputStream(in, aesCipher);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[BUF_SIZE];
int avail;
while ((avail = cin.read(buf)) != -1)
{
out.write(buf, 0, avail);
}
return new ByteArrayInputStream(out.toByteArray());
}
catch (IOException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static void crypt(Key key, InputStream in, OutputStream out,
String algorithm, int mode) throws CryptoException
{
try
{
InputStream encIn = getCipherInputStream(key, in, algorithm, mode);
byte[] buf = new byte[BUF_SIZE];
int avail;
while ((avail = encIn.read(buf)) != -1)
{
out.write(buf, 0, avail);
}
out.flush();
}
catch (IOException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static CipherInputStream getCipherInputStream(Key key, InputStream in,
String algorithm, int mode) throws CryptoException
{
try
{
Cipher rsaCipher = Cipher.getInstance(algorithm);
rsaCipher.init(mode, key);
// encrypt input
return new CipherInputStream(in, rsaCipher);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static CipherOutputStream getCipherOutputStream(Key key,
OutputStream out, String algorithm, int mode) throws CryptoException
{
try
{
// initialize RSA Cipher
Cipher rsaCipher = Cipher.getInstance(algorithm);
rsaCipher.init(mode, key);
// encrypt input
return new CipherOutputStream(out, rsaCipher);
}
catch (InvalidKeyException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchPaddingException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
catch (NoSuchAlgorithmException ex)
{
throw new CryptoException(ex.getMessage(), ex);
}
}
public static byte[] calcMD5(byte[] b) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(b);
}
}