El Digital Signature Algorithm es un algoritmo de cifrado asimétrico o de clave pública.
Con esta clase que utiliza el algoritmo DSA podemos verificar la autenticidad de un mensaje, dada una clave publica y la firma del mensaje.
Tambien podemos generar pares claves publica, privada y generar firmas de datos usando la clave privada generada.
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.Signature; import java.security.SignatureException; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.DSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class dsaCryptoUtils { public dsaCryptoUtils() throws Exception{ throw new Exception("Esta clase contiene solo metodos estaticos. No deberia ser instanciada."); } /** * Genera las claves publica y privada y las guarda en archivos * @param pubFName Nombre del archivo de la clave publica * @param privFName Nombre del archivo de la clave privada * @throws java.lang.Exception */ public static void genKeys(String pubFName, String privFName) throws Exception { KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA"); SecureRandom secrand = new SecureRandom(); keygen.initialize(1024, secrand); KeyPair keys = keygen.generateKeyPair(); saveFile(pubFName, keys.getPublic().getEncoded()); saveFile(privFName, keys.getPrivate().getEncoded()); } /** * Firma una cadena usando la clave privada proporcionada y guarda la firma en un archivo * @param message Cadena que sera firmada * @param privFName Nombre del archivo que contiene la clave privada * @param signFName Nombre del archivo donde se guardara la firma * @throws java.lang.Exception */ public static void signMessage(String message, String privFName, String signFName) throws Exception { try { Signature signalg = Signature.getInstance("DSA"); signalg.initSign(loadPrivateKey(privFName)); signalg.update(message.getBytes()); byte[] signature = signalg.sign(); saveFile(signFName, signature); } catch (NoSuchAlgorithmException ex) { throw new Exception("DSA no existe: " + ex.getMessage()); } catch (InvalidKeyException ex) { throw new Exception("Clave invalida: " + ex.getMessage()); } catch (SignatureException ex) { throw new Exception("Imposible firmar mensaje: " + ex.getMessage()); } catch (Exception ex) { throw new Exception("Imposible guardar firma: " + ex.getMessage()); } } /** * Verifica si la firma de una cadena es autentica usando la calve publica * @param message Cadena en juicio * @param signFName Nombre del archivo que contiene la firma DSA * @param pubFName Nombre del archivo que contiene la clave publica * @return Retorna True si la cadena es autentica y False caso contrario * @throws java.lang.Exception */ public static boolean verifySignedMessage(String message, String signFName, String pubFName) throws Exception { Signature verifyalg = Signature.getInstance("DSA"); verifyalg.initVerify(loadPublicKey(pubFName)); verifyalg.update(message.getBytes()); return (verifyalg.verify(loadFile(signFName))); } /** * Carga la clave privada del archivo con nombre privFName * @param privFName * @return */ private static DSAPrivateKey loadPrivateKey(String privFName) throws Exception { byte[] privKeyBytes = loadFile(privFName); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privKeyBytes); DSAPrivateKey privKey = (DSAPrivateKey) keyFactory.generatePrivate(privSpec); return privKey; } /** * Carga la clave publica del archivo con nombre privFName * @param pubFName * @return */ private static DSAPublicKey loadPublicKey(String pubFName) throws Exception { byte[] pubKeyBytes = loadFile(pubFName); KeyFactory keyFactory = KeyFactory.getInstance("DSA"); X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes); DSAPublicKey pubKey = (DSAPublicKey) keyFactory.generatePublic(pubSpec); return pubKey; } /** * Guarda en un archivo un arreglo de bytes * @param fileName Nombre del archivo donde se escribira el arreglo de bytes * @param justByteArray Arreglo de bytes * @throws java.lang.Exception */ private static void saveFile(String fileName, byte[] justByteArray) throws Exception { FileOutputStream outStream = new FileOutputStream(fileName); outStream.write(justByteArray); outStream.close(); } /** * Carga un archivo a un arreglo de bytes * @param fileName Nombre del archivo que se cargara a un arreglo de bytes * @return Arreglo de bytes del archivo fileName * @throws java.lang.Exception */ private static byte[] loadFile(String fileName) throws Exception { File file = new File(fileName); InputStream is = new FileInputStream(file); long length = file.length(); byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { throw new Exception("No se leyo todo el archivo " + file.getName()); } is.close(); return bytes; } }
Comentarios Recientes