Firma digital de datos usando DSA

Java Agregar comentario

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;
	}
}

Deja un Comentario

WP Theme & Icons by N.Design Studio
Posts en RSS Comentarios en RSS Iniciar sesión