Concepto de contraseña asimétrica
1. La principal diferencia de los algoritmos de cifrado simétrico es que las claves de cifrado y descifrado son diferentes, uno es público (clave pública) y la otra es confidencial (clave privada). Principalmente resuelve el problema de la gestión de la asignación clave de los algoritmos de cifrado simétrico y mejora la seguridad del algoritmo.
2. La eficiencia de cifrado y descifrado de los algoritmos de cifrado asimétrico es relativamente baja. En el diseño de algoritmos, los algoritmos de cifrado asimétricos tienen requisitos estrictos sobre la longitud de los datos cifrados. Por ejemplo, el algoritmo RSA requiere que los datos se cifren no deben ser superiores a 53 bytes.
3. Los algoritmos de cifrado asimétrico se utilizan principalmente para intercambiar claves de algoritmos de cifrado simétrico, en lugar del intercambio de datos.
4. Java6 proporciona dos algoritmos que implementan DH y RSA. El castillo hinchable proporciona soporte de algoritmo E1Gamal. Además de los tres algoritmos anteriores, también hay un algoritmo ECC, y actualmente no existe un componente de código abierto relevante para proporcionar soporte.
Se requieren dos claves para el cifrado o el descifrado, divididos en claves públicas y privadas
Características: alta seguridad, velocidad lenta
usar
【Intercambio de claves (DH)】
Sin determinar la clave común, ambas partes generan la clave y no proporcionan trabajo de cifrado. El cifrado y el descifrado también requieren otros algoritmos de cifrado simétrico para implementar.
Ejemplo de algoritmo DH
import javax.crypto.keyagreement; import javax.crypto.interfaces.dhprivatekey; import javax.crypto.interfaces.dhpublickey; import javax.crrypto.spec.dhparameterspec; import java.security.*; import java.security.spec.pkcodeS8C; java.security.spec.x509CodedkeySpec; import java.util.hashmap; import java.util.map; // 1 Generar la clave de origen // 2 La clave pública de la fuente se entrega al objetivo, y el objetivo genera la clave pública y la clave privada a través de la fuente. // 3 La clave pública del objetivo se entrega a la fuente // 4 Ambas partes usan la clave pública de la otra parte y su propia clave privada para generar la clave local // 5 si ambas partes generan la clave local de la misma manera, complete la clase pública de intercambio de claves dhutil {public static final string public_key = "dh_public_key"; public static final String private_key = "dh_private_key"; /** * Generar el par de teclas de origen * @return * @throws Exception */public static map <String, object> initSourceKey () lanza excepción {// Cree una instancia de keyPairGenerator, seleccione el algoritmo DH KeyPairGenerator KeyPairGenerator = KeyPoirGenerator.getInstance ("DH"); // Inicializar la longitud de la tecla, predeterminado 1024, rango opcional 512-65536 y múltiplos de 64 keypairGenerator.initialize (1024); // Generar el par de teclas KeyPair KeyPair = KeyPairGenerator.GenerateKeypair (); Dhpublickey dhpublickey = (dhpublickey) keypair.getPublic (); Dhprivatekey dhprivateKey = (dhprivatekey) keypair.getPrivate (); // Coloque el par de teclas en mapa de map <string, object> keyMap = new HashMap <String, Object> (); kymap.put (public_key, dhpublickey); kymap.put (private_key, dhprivatekey); return keymap; } / ** * Genere el par de la clave de destino a través de la clave pública de origen * @param SourcePublicKey * @return * @throws Exception * / public static map <String, object> inItTargetKey (byte [] SourcePublicKey) lanza la excepción {KeyFactory KeyFactory = KeyFactory.getInStance ("dh"); // Utilice la clave pública de origen, genere KeySpec y use KeyFactory para generar información de origen Información relacionada con Key KeyCodeDeSpec KeySpec = new X509EncodedKeySpec (SourcePublicKey); Dhpublickey sourcePublic = (dhpublickey) keyFactory.GeneratePublic (KeySpec); Dhparameterspec dhpublicKeyParams = SourcePublic.getParams (); KeyPairGenerator KeyPairGenerator = KeyPairGenerator.GetInstance ("Dh"); KeyPairGenerator.initialize (dhpublicKeyParams); KeyPair KeyPair = KeyPairGenerator.GenerateKePAir (); Dhpublickey dhpublickey = (dhpublickey) keypair.getPublic (); Dhprivatekey dhprivateKey = (dhprivatekey) keypair.getPrivate (); // Coloque el par de teclas en mapa de map <string, object> keyMap = new HashMap <String, Object> (); kymap.put (public_key, dhpublickey); kymap.put (private_key, dhprivatekey); return keymap; } / *** Use la clave pública de una parte y la clave privada de la otra parte para generar la clave local* @return* / public static byte [] generatelocalsecretkey (byte [] apublickey, byte [] bprivatekey) lanza excepción {keyFactory keyFactory.getininstance ("dh"); // Use una clave pública, genere KeySpec y use KeyFactory para generar una información relacionada con la tecla pública x509CodedKeySpec KeySpec = new X509EncodedKeSpec (ApublicKey); PublicKey PublicKey = KeyFactory.GeneratePublic (KEYSPEC); // Use B Key private, genere B PrivateKey Información relacionada con la tecla PKCS8CodedKeySpec PKCS8EncodedKeySpec = new PKCS8EncodedKeSpec (BPrivateKey); PrivateKey privateKey = keyFactory.GeneratePrivate (PKCS8EncodedKeySpec); // cifrar la tecla pública de A y la tecla privada de B a través de KeyAgreement KeyAgreement KeyAgreement = KeyAgreement.GetInStance ("DH"); KeyAgreement.init (PrivateKey); KeyAgreement.dophase (PublicKey, True); return keyAgreement.GeneratesECret ("AES"). // El algoritmo también se puede usar para calcular el método predeterminado sin seleccionar el algoritmo} // Obtener la matriz de byte pública Byte Public Static Byte [] getPublicKey (map <string, object> map) {return ((dhpublickey) map.get (public_key)). GetiCoded (); } // Obtenga la matriz de bytes de la clave privada Public static byte [] getPrivateKey (map <string, object> map) {return ((dhprivatekey) map.get (private_key)). GetEncoded (); } public static void main (string [] args) lanza la excepción {byte [] fuente_public_key; byte [] fuente_private_key; byte [] fuente_local_key; byte [] target_public_key; byte [] target_private_key; byte [] target_local_key; MAP <String, Object> SourceKey = InitSourceKey (); fuente_public_key = getPublicKey (SourceKey); fuente_private_key = getPrivateKey (SourceKey); System.out.println ("Clave pública de origen:"+bytestoHex.FrombyTestoHex (fuente_public_key)); System.out.println ("Clave privada de origen:"+bytestoHex.FrombyTestoHex (fuente_private_key)); Map <string, object> targetKey = inItTargetKey (getPublicKey (SourceKey)); target_public_key = getPublicKey (TargetKey); Target_private_key = getPrivateKey (TargetKey); System.out.println ("Target Public Key:"+bytestoHex.FrombyTestoHex (Target_public_key)); System.out.println ("Target private Key:"+bytestoHex.FrombyTestoHex (Target_Private_Key)); fuente_local_key = generatelocalSecretkey (target_public_key, fuente_private_key); Target_local_key = GenerAtelocalSecretkey (fuente_public_key, target_private_key); System.out.println ("Clave local de origen:"+bytestoHex.FrombyTestoHex (fuente_local_key)); System.out.println ("Target Local Key:"+bytestoHex.FrombyTestoHex (Target_local_key)); }}【Cifrado/Decryto (RSA) 】【 Firma digital (RSA)】
El algoritmo RSA es posterior al algoritmo DH, y todas estas cinco letras son las primeras letras del nombre humano. El algoritmo DH es el primer sistema criptográfico asimétrico.
El algoritmo RSA tiene una velocidad informática lenta y no es adecuado para cifrar grandes cantidades de datos. Una solución es mezclar métodos de cifrado RSA y simétricos, los datos de cifrado utilizando métodos de cifrado simétrico y las claves de cifrado simétricas se cifran utilizando algoritmos RSA. Debido a que la clave es muy corta, el tiempo no es demasiado. De hecho, la única desventaja de los métodos de cifrado simétrico es que la clave es difícil de aprobar, y los métodos de cifrado simétrico también son difíciles de descifrar.
Escenarios aplicables de RSA:
(1) El servidor genera una clave pública y una clave privada, y publica la clave pública.
(2) El cliente usa una clave pública para cifrar los datos y entregarlo al servidor. Otros no pueden entender los datos cifrados.
(3) El servidor utiliza una clave privada para descifrar los datos y ver los datos enviados por el usuario.
En este caso, la clave pública es como un buzón, y todos pueden enviar un mensaje a este buzón, pero solo aquellos que tienen las claves del buzón pueden descargar y ver las cartas en este buzón.
RSA Escenario aplicable 2:
(1) El Emperador genera una clave pública y una clave secreta, y publicita la clave pública.
(2) El Emperador emitió un edicto para informar al mundo. Hay dos cadenas de números en la esquina inferior derecha del edicto. La primera cadena es una cadena aleatoria, y la segunda cadena es el resultado de cifrar la primera cadena con una clave privada.
(3) Algunas personas no creen que el edicto haya sido escrito por el Emperador, por lo que descifraron la segunda cadena de números usando la clave pública. Después de descifrar, descubrieron que era lo mismo que la primera cadena de números, lo que significa que fue escrito por el Emperador. Debido a que la mayoría de las personas no tienen una clave, no pueden cifrar los datos que pueden descifrarse con la clave pública.
En este caso, la clave pública se usa para el descifrado y la clave privada se usa para el cifrado. Esto se puede usar para demostrar que el anuncio fue enviado por alguien. Es equivalente a una firma.
De hecho, no hay necesidad de ser particularmente larga para las firmas. En términos generales, las firmas son de longitud fija. Si desea tener una longitud fija, puede usar el algoritmo MessageDigest, como la serie MD5 y SHA. Por lo tanto, hay una variedad de algoritmos de firma, como MD5 Withrsa, etc.
Ejemplos de cifrado/descifrado RSA
import javax.crypto.cipher; import java.security.keypair; import java.security.keypairGenerator; import java.security.publickey; import java.security.interfaces.rsaprivatekey; import java.security.interfaces.rsapublickey; importación de importación; importar; importar; importación; importar; importación; java.util.map;/*** RSA Herramienta de cifrado*/public class rsautil {public static final String public_key = "rsa_public_key"; public static final String private_key = "rsa_private_key"; / ** * Clave de inicialización * @return * @throws Exception */ public static map <string, object> initkey () lanza la excepción {KeyPairGenerator KeyPairGenerator = KeyPairGenerator.getInstance ("RSA"); keyPairGenerator.initialize (1024); // 512-65536 y múltiplos de 64 KEYPAIR KEYPAIR = KeyPairGenerator.GenerateKeypair (); Rsapublickey publickey = (rsapublickey) keypair.getPublic (); Rsaprivatekey privateKey = (rsaprivatekey) keypair.getPrivate (); Map <string, object> keyMap = new HashMap <String, Object> (); kymap.put (public_key, public key); kymap.put (private_key, privatekey); return keymap; } public static rsapublickey getPublicKey (map <string, object> keyMap) {return (rsapublickey) keyMap.get (public_key); } public static rsaprivatekey getPrivateKey (map <string, object> keyMap) {return (rsaprivateKey) keyMap.get (private_key); } / ** * Encrypt Data usando la clave pública * @param data * @param public keyk * @return * @throws excepción * / public static byte [] cifryp (byte [] data, rsapublickey publickey) lanza la excepción {cipher cipher = cipher.getInstance ("RSA"); cipher.init (cipher.encrypt_mode, public key); return cipher.dofinal (datos); } / ** * Use la clave privada para descifrar * @param data * @param privatekey * @return * @throws excepción * / public static byte [] Decrypt (byte [] data, rsaprivatekey privatekey) lanza excepción {cipher cipher = cipher.getInstance ("rsa"); cipher.init (cipher.decrypt_mode, privateKey); return cipher.dofinal (datos); } public static void main (string [] args) lanza la excepción {string data = "Jay chou-dongfeng break"; Map <string, object> keyMap = initkey (); byte [] miwen = encrypt (data.getBytes (), getPublicKey (keyMap)); System.out.println ("Contenido cifrado:"+bytestoHex.FrombyTesthex (Miwen)); byte [] sencillo = Decrypt (Miwen, GetPrivateKey (KEYMAP)); System.out.println ("Contenido descifrado:"+nueva cadena (simple)); }}Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.