Red de conocimiento informático - Consumibles informáticos - ¥¥¥¥Firma digital basada en lenguaje java¥¥¥¥¥

¥¥¥¥Firma digital basada en lenguaje java¥¥¥¥¥

El proyecto de graduación tomará al menos 2 meses. Recién estás comenzando. Es demasiado tarde si no copias y pegas~

Inicio rápido con cifrado Java y firma digital. Programación

Este artículo habla principalmente sobre cifrado y firmas digitales en criptografía, y cómo utilizarlas en Java. Para aquellos interesados ​​en la criptografía, recomiendo leer el libro de Bruce Schneier: Applied Crypotography. El aspecto de seguridad se ha mejorado enormemente en la versión de lanzamiento de jdk1.5 y también proporciona soporte directo para el algoritmo RSA. Ahora comenzamos a resolver el problema con un ejemplo (este artículo es solo una breve introducción):

1. Conceptos comúnmente utilizados en criptografía

1) Resumen de mensajes:

Esta es una tecnología utilizada junto con códigos de autenticación de mensajes para garantizar la integridad del mensaje.

Utiliza principalmente un algoritmo de función hash unidireccional, que se puede utilizar para verificar la integridad del mensaje y guardarlo directamente en forma de texto mediante contraseñas hash. Los algoritmos actualmente más utilizados son MD4, MD5 y SHA-1. jdk1.5 proporciona todo lo anterior. Con soporte, es muy sencillo realizar un resumen de mensajes en java. java.security.MessageDigest proporciona un método de operación simple:

/**

*MessageDigestExample.java

*Copyright 2005-2-16

*/

importar java.security.MessageDigest;

/ **

*Un algoritmo de resumen de mensaje único que no utiliza contraseñas. Puede usarse para ocultar y guardar mensajes de texto sin formato (como contraseñas)

*/

.

clase pública MessageDigestExample{

public static void main(String[] args) lanza una excepción{

if(args.length!=1){

System.err.println("Uso: java MessageDigestExample texto ");

System.exit(1);

}

byte[] PlainText= args[0].getBytes("UTF8");

//Utilice getInstance("algorithm") para obtener el resumen del mensaje, aquí se utiliza el algoritmo de 160 bits de SHA-1

MessageDigest messageDigest=MessageDigest.getInstance("SHA-1"

System.out.println("\n" messageDigest.getProvider().getInfo()); p> //Comienza a usar el algoritmo

messageDigest.update (plainText);

System.out.println("\nDigest: ");

/ /Resultados de la operación del algoritmo de salida

System.out.println( new String(messageDigest.digest(), "UTF8")); /p>

El cifrado también se puede implementar a través del código de autenticación de mensajes, javax .crypto.Mac proporciona una solución. Las partes interesadas pueden consultar la documentación API relevante. Este artículo solo presenta brevemente qué es un algoritmo de resumen.

2) Cifrado de clave privada:

El resumen del mensaje solo puede verificar la integridad del mensaje, pero es unidireccional y no puede cifrar el mensaje de texto sin formato si así lo desea. cifre el mensaje de texto sin formato, solo Para usar otros algoritmos, para garantizar la confidencialidad, necesitamos usar criptografía de clave privada para intercambiar mensajes privados.

Esto se entiende mejor utilizando un algoritmo simétrico.

Por ejemplo: A usa una clave para cifrar un archivo, y si B lee el archivo, necesita la misma clave que A. Ambas partes comparten una clave privada (y en un entorno web, la clave privada se transfiere fácilmente durante la transmisión. Escuchado ):

Si usa cifrado de clave privada, primero necesita una clave. Puede usar javax.crypto.KeyGenerator para generar una clave (java.security.Key) y luego pasarla a una herramienta de cifrado. (javax .crypto.Cipher), la herramienta luego utiliza el algoritmo correspondiente para cifrar. Los principales algoritmos simétricos son: DES (la clave real solo usa 56 bits), AES (admite tres longitudes de clave: 128, 192, 256 bits). normalmente 128 bits primero, otros incluyen DESede, etc. jdk1.5 también proporciona soporte para algoritmos simétricos. El siguiente ejemplo utiliza el algoritmo AES para cifrar:

/**

*PrivateExmaple. .java

*Copyright 2005-2-16

*/

importar javax.crypto.Cipher;

importar javax.crypto .KeyGenerator;

importar java.security.Key;

/**

*Cifrado de clave privada para garantizar la confidencialidad del mensaje

* /

clase pública PrivateExample{

public static void main(String[] args) lanza una excepción{

if(args.length!= 1){

System.err.println("Uso: java PrivateExample lt; textgt;");

System.exit(1);

byte[] PlainText=args[0].getBytes("UTF8");

//Forma una clave a través de KeyGenerator

System.out.println ("\nStart generar clave AES");

KeyGenerator keyGen=KeyGenerator.getInstance("AES");

keyGen.init(128);

Clave key=keyGen .generateKey();

System.out.println("Termina de generar la clave DES");

//Obtiene una clase de cifrado privada Cipher, ECB es el método de cifrado, PKCS5Padding es el método de llenado

Cipher cipher=Cipher.getInstance("AES/ECB/PKCS5Padding");

System.out.println("\n" cipher.getProvider( ).getInfo( ));

//Usar cifrado privado

System.out.println("\nIniciar cifrado:");

init(Cipher.ENCRYPT_MODE ,clave);

byte[] cifrado

Text=cipher.doFinal(plainText);

System.out.println("Finalizar cifrado:");

System.out.println(new String(cipherText, "UTF8" ));

System.out.println("\nIniciar descifrado: ");

cipher.init(Cipher.DECRYPT_MODE, clave); [] newPlainText=cipher.doFinal(cipherText);

System.out.println("Finalizar descifrado:");

System.out.println(new String(newPlainText," UTF8"));

}

}

3) Cifrado de clave pública:

Como se mencionó anteriormente, el cifrado de clave privada requiere una La clave es compartida, entonces, ¿cómo transferir la clave? En un entorno web, la transmisión directa es fácil de interceptar. Afortunadamente, ha surgido el cifrado de clave pública. El cifrado de clave pública también se denomina cifrado asimétrico. El algoritmo asimétrico utiliza un par de claves, una clave pública y una clave privada para descifrar los datos cifrados con la clave pública (se pueden utilizar al mismo tiempo); uso de la clave privada Los datos cifrados con una clave pública solo pueden descifrarse (firmarse) mediante la clave pública.

Pero la velocidad es muy lenta (de 100 a 1000 veces más lenta que el cifrado de clave privada. Los principales algoritmos de clave pública son RSA, incluidos Blowfish, Diffie-Helman, etc. jdk1.5 proporciona soporte para RSA, lo cual es una mejora:

/**

*PublicExample.java

*Copyright 2005-2-16

*/

importar java.security.Key;

importar javax.crypto.Cipher;

importar java.security.KeyPairGenerator;

importar java.security.KeyPair

/**

*Un ejemplo de cifrado de cifrado público simple, la clase Cipher utiliza los cifrados públicos y privados generados por KeyPairGenerator

*/

clase pública PublicExample{

public static void main(String[] args) lanza una excepción{

if(args.length!=1){

Sistema .err.println("Uso: java PublicExample lt; textgt;");

System.exit(1);

}

byte[ ] texto plano; =args[0].getBytes("UTF8");

//Constituir una clave RSA

System.out.println("\nEmpezar a generar clave RSA") ;

KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");

keyGen.initialize(1024);

KeyPair key=keyGen.generateKeyPair(); >

System.out.println("Termina de generar la clave RSA");

//Obtén una clase de cifrado RSA y usa cifrado de cifrado público

Cipher cipher =Cipher.getInstance ("RSA/ECB/PKCS1Padding");

System.out.println("\n" cipher.getProvider().getInfo());

System.out.println ("\nIniciar cifrado");

cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());

byte[] cipherText=cipher.doFinal( PlainText);

System.out.println("Finalizar cifrado: ");

System.out.println(new String(cipherText, "UTF8"));

//Usa clave privada para descifrar

System.out.println("\nIniciar descifrado");

cipher.init(Cipher.DECRYPT_MODE, key.getPrivate());

byte[] newPlainText= cipher.doFinal(cipherText);

System.out.println("Finalizar descifrado:");

System.out.println(new String(newPlainText, "UTF8"))

}

}

4) Firma digital:

Firma digital, que es el primer paso para determinar la identidad del Partes comunicantes que intercambian mensajes. Un nivel. Arriba, A usa la clave pública para cifrar los datos y los envía a B. B usa la clave privada para descifrar y obtener los datos requeridos. Dado que la clave pública se usa para cifrar, surge la pregunta de cómo verificar que el mensaje sea. enviado por A? Como se mencionó anteriormente, la clave privada es única, por lo que A puede usar la clave privada de A para cifrar, y luego B puede usar la clave pública de A para descifrar. El principio de la firma digital se basa en esto y generalmente para demostrar la autenticidad. de los datos enviados, el contenido breve del mensaje se obtiene utilizando el resumen del mensaje y luego la clave privada se usa para cifrar los datos hash y enviarlos junto con el mensaje.

Java proporciona un buen soporte para firmas digitales y la clase java.security.Signature proporciona firmas de mensajes:

/**

*DigitalSignature2Example.java

*Copyright 2005-2-16

*/

importar java.security.Signature;

importar java.security.KeyPairGenerator;

importar java.security.KeyPair;

importar java.security.SignatureException;

/**

*Firma digital, utilizando clave privada RSA para emparejar el mensaje Digest la firma y luego use la prueba de verificación pública

*/

public class DigitalSignature2Example{

public static void main(String[] args) throws Exception{

if(args.length!=1){

System.err.println("Uso: java DigitalSignature2Example lt; textgt;"

System); exit(1);

}

byte[] PlainText=args[0].getBytes("UTF8");

//Formulario RSA público. clave Sí

System.out.println("\nComenzar a generar la clave RSA");

KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA");

keyGen .initialize(1024);

KeyPair key=keyGen.generateKeyPair();

System.out.println("Terminar de generar la clave RSA");

//Usar firma privada

Firma sig=Signature.getInstance("SHA1WithRSA");

sig.initSign(key.getPrivate());

sig.update(plainText);

byte[] firma=sig.sign();

System.out.println(sig.getProvider().getInfo());

System.out.println("\nFirma: ");

System.out.println(new String(firma, "UTF8")); //Usar verificación de clave pública

System.out.println("\nIniciar verificación de firma");

sig.initVerify(key.getPub

lic());

sig.update(plainText);

prueba{

if(sig.verify(signature)){

System.out.println("Firma verificada");

}else System.out.println("Firma fallida");

}catch(SignatureException e){

System.out.println("Falló la firma");

}

}

}

5 ) certificado digital.

Hay otro problema, es decir, el problema de la clave pública. A cifra el mensaje con la clave privada, luego, después de que B recibe el mensaje, utiliza la clave pública proporcionada por A para descifrarlo; Es un C desagradable que cifra el mensaje. Interceptado, luego lo cifró con su propia clave privada y al mismo tiempo envió su clave pública a B y le dijo a B que era la clave pública de A. Como resultado... Esta vez, se necesita una agencia intermediaria para hablar (creo que la Autoridad, estoy en lo cierto), apareció la Autoridad de Certificación (también conocida como CA). Las instituciones de CA famosas incluyen Verisign, etc. El estándar actual de la industria para la certificación digital es: CCITT's X. .509:

Certificado Digital: Encapsula una identidad junto con una clave pública y la firma digitalmente por un tercero llamado autoridad de certificación o CA.

Almacén de claves: la plataforma Java le proporciona un almacén de claves, que se utiliza como biblioteca de recursos para claves y certificados. Físicamente, el almacén de claves es un archivo llamado .keystore de forma predeterminada (existe una opción para convertirlo en un archivo cifrado). Las claves y los certificados pueden tener nombres (llamados alias), cada uno de los cuales está protegido por una contraseña única. El almacén de claves en sí también está protegido con contraseña; puede elegir que cada contraseña de alias coincida con la contraseña del almacén de claves maestro.

Usando la herramienta keytool, hagamos una autocertificación (confíe en mi certificación):

1. Cree el almacén de claves keytool -genkey -v -alias feiUserKey - keyalg RSA está en su propio directorio de inicio de forma predeterminada (el sistema Windows es c:\documents and settings\lt; su nombre de usuario gt; el archivo .keystore en el directorio Usamos el algoritmo RSA para generar un certificado autofirmado con el alias feiUserKey). Se utiliza -keystore mm, cree un archivo de almacén de claves mm en el directorio actual para guardar la clave y el certificado.

2. Ver certificados: keytool -list enumera todos los certificados en el almacén de claves

También puede ingresar keytool -help en DOS para ver la ayuda.

2. Firma JAR

Hemos aprendido a crear nuestro propio certificado y ahora podemos empezar a entender cómo firmar un archivo JAR. Un archivo JAR equivale a un ZIP. archivo en Java Permite empaquetar múltiples archivos de clase Java en un archivo con una extensión .jar, y este archivo jar se puede firmar digitalmente para verificar su origen y autenticidad. El destinatario del archivo JAR puede decidir si confiar en el código basándose en la firma del remitente y puede estar seguro de que el contenido no ha sido alterado antes de recibirlo. También en la implementación, el acceso a los recursos de la máquina se puede asignar según la identidad del firmante colocando declaraciones de control de acceso en el archivo de política. De esta forma se puede realizar la verificación de seguridad del acceso a algunos Applets.

Utilice la herramienta jarsigner para firmar archivos jar:

Ahora supongamos que tenemos un archivo Test.jar (se puede generar utilizando la herramienta de línea de comandos jar):

jarsigner Test.jar feiUserKey (aquí creamos el certificado para este alias arriba), se puede ingresar información detallada en jarsigner para ver la ayuda

Verifique su autenticidad: jarsigner -verify Test.jar (tenga en cuenta que la verificación es si el jar ha sido modificado, pero no se verifica la reducción. Si se agrega contenido nuevo, se solicitará, pero no se solicitará la reducción)

Usar subprograma: lt; code="Test.class" archive.="Test.jar" width="150" height="100"gt;lt;/appletgt;Entonces el navegador le preguntará: permita esta sesión-denegue-siempre permita-ver el certificado. , etc.

3. SSL Secure Sockets Layer y TLS Transport Layer Security

Se utilizan Secure Sockets Layer y Transport Layer Security. Un protocolo para construir un canal de comunicación seguro entre un cliente y un servidor. También se utiliza para autenticar clientes en servidores y (con menos frecuencia) para autenticar clientes en servidores. Este protocolo es relativamente común en las aplicaciones del navegador. El candado en la parte inferior de la ventana del navegador indica que SSL/TLS es válido:

1) Cuando se usa SSL/TLS (generalmente se usa la clase .ssl.SSLServerSocketFactory). una buena clase de fábrica de SSLServerSocker, los lectores que estén familiarizados con la programación de Socket pueden practicar. Después de escribir en el lado del servidor, ingrese .ssl.keyStore=keystore en el navegador (al crear el certificado, el nombre debe ser el nombre del host, como por ejemplo). localhost) y javax.net.ssl.keyStorePassword=Su contraseña