package org.fmeyer.crypto;
/*
* Copyright (c) 2006 Fernando Meyer
* Author Fernando Meyer <fernando@fmeyer.org>
* Java doc de referencia: http://java.sun.com/j2se/1.4.2/docs/api/javax/crypto/package-summary.html
* Documentacao de referencia: http://en.wikipedia.org/wiki/Triple_DES
*/
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class TripleDES {
/**
* Gera a chave baseada no algoritmo DES
*
* @return {@link SecretKey}
* @throws NoSuchAlgorithmException
*/
public SecretKey generateKey() throws NoSuchAlgorithmException {
KeyGenerator keygen = KeyGenerator.getInstance("DESede");
return keygen.generateKey();
}
/**
* Grava a chave secreta em um arquivo para poder transportar para qualquer
* lugar. como em um pendrive por exemplo
*
* @param DESkey chave a ser persistida em disco
* @param filehandler handler para arquivo em disco
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public void writeKey(SecretKey DESkey, File filehandler)
throws IOException, NoSuchAlgorithmException,
InvalidKeySpecException {
/*
* Converte a chave em um array de bytes para ser gravada em disco.
*/
byte[] rawkey = keytobytearray(DESkey);
/*
* Grava a chave propriamente dita no handler de arquivo passado
*/
FileOutputStream out = new FileOutputStream(filehandler);
out.write(rawkey);
out.close();
}
/**
*
* @param DESkey chave a ser convertida para string
* @return byte[]
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public String keytostring(SecretKey DESkey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
String tmpKey = new String();
byte[] rawkey = keytobytearray(DESkey);
for (byte b : rawkey) {
tmpKey += Integer.toHexString(b);
}
return tmpKey;
}
/**
*
* @param strKey chave no formato string para ser convertida para um array de bytes
* @return byte[]
*/
public byte[] stringtokey(String strKey) {
BigInteger big = new BigInteger(strKey, 16);
byte[] valor = big.toByteArray();
return valor;
}
/**
*
* @param DESkey chave no formato {@link SecretKey} para ser convertida para um array de bytes
* @return byte[]
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public byte[] keytobytearray(SecretKey DESkey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec keyspec = (DESedeKeySpec) keyfactory.getKeySpec(DESkey,
DESedeKeySpec.class);
byte[] rawkey = keyspec.getKey();
return rawkey;
}
/**
* L� a chave Tipla de um arquivo especifico.
*
* @param filehandler filehandler do arquivo em disco que contem uma chave serializada
* @return {@link SecretKey}
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
*/
public SecretKey readKey(File filehandler) throws IOException,
NoSuchAlgorithmException, InvalidKeyException,
InvalidKeySpecException {
/*
* Le os bytes de um arquivo para um array na memoria para ser
* convertido a uma chave
*/
DataInputStream in = new DataInputStream(new FileInputStream(filehandler));
byte[] rawkey = new byte[(int) filehandler.length()];
in.readFully(rawkey);
in.close();
// Converte o array de bytes para uma chave SecretKey
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
return key;
}
/**
* Usa uma chave especifica para criptografar um inputstream para um
* outputstream este metodo usa a classe CipherOutputStream para
* criptografar e gravar os arquivos ao mesmo tempo.
* @param key Chave a ser usada na criptogravia
* @param in texto a ser criptografado.
* @return {@link String}
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws NoSuchPaddingException
* @throws IOException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
*/
public String encrypt(SecretKey key, String in)
throws NoSuchAlgorithmException, InvalidKeyException,
NoSuchPaddingException, IOException, IllegalBlockSizeException,
BadPaddingException {
// Pega a instancia do engine de criptografia
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.ENCRYPT_MODE, key);
// Pega os bytes do string
byte[] buffer = new byte[in.length()];
buffer = in.getBytes();
buffer = cipher.doFinal(buffer);
// monta o retorno para o string
String ret = new String(buffer);
// por seguranca nao deixar dados no array
// ao sair da funcao o objeto ret vai ser coletado pelo garbage colector
java.util.Arrays.fill(buffer, (byte) 0);
return ret;
}
/**
* Usa uma chave especifica para descriptografar um inputstream para um
* outputstream
*
* @param key Chave usada na operacao
* @param in Texto criptografado a ser decriptografado
* @return {@link SecretKey}
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws IOException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws BadPaddingException
*/
public String decrypt(SecretKey key, String in)
throws NoSuchAlgorithmException, InvalidKeyException,
IllegalBlockSizeException, NoSuchPaddingException,
BadPaddingException {
// Pega a instancia do engine de criptografia
Cipher cipher = Cipher.getInstance("DESede");
cipher.init(Cipher.DECRYPT_MODE, key);
// Pega os bytes do string
byte[] buffer = new byte[in.length()];
buffer = in.getBytes();
// monta o retorno para o string
buffer = cipher.doFinal(buffer);
return new String(buffer);
}
}