Siento que ha pasado mucho tiempo desde la última vez que escribí un blog. Déjame quejarme primero. Este mes, la compañía ha estado trabajando horas extras, publicando y lanzando la publicación, y los nuevos proyectos son demasiado ajustados, por lo que no diré mucho sobre los específicos. Hoy, es realmente importante hablar sobre el cifrado asimétrico. El cifrado asimétrico es indispensable en nuestra vida diaria.
concepto
Antes de hablar sobre RSA, primero hablemos sobre qué es el cifrado asimétrico. Cuando se habló de cifrado simétrico, se dijo una vez que los algoritmos de cifrado simétrico usan la misma clave secreta al encriptar y descifrar, y ambas partes para encriptar y descifrar deben usar la misma clave para comunicarse normalmente. El cifrado asimétrico no es el caso. El algoritmo de cifrado asimétrico requiere dos claves para cifrar y descifrar, a saber, la clave pública y la clave privada.
Una cosa a tener en cuenta es que la clave pública y la clave privada deben ser un par. Si los datos están encriptados con la clave pública, solo la clave privada correspondiente se puede descifrar y viceversa. Dado que el cifrado y el descifrado usan dos claves diferentes, este algoritmo se llama algoritmo de cifrado asimétrico.
Proceso de trabajo
Como se muestra en la figura a continuación, los datos se transmiten utilizando cifrado asimétrico.
Los algoritmos principales utilizados en el cifrado asimétrico incluyen: RSA, Elgamal, algoritmo de mochila, Rabin, DH, ECC (algoritmo de cifrado de curva elíptica), etc. Hoy, hoy introduciremos RSA. En cuanto a otros algoritmos, elegiremos algunos para presentarlos más tarde.
RSA
De hecho, RSA apareció ya en 1978, y fue el primer algoritmo el que se puede utilizar tanto para el cifrado de datos como para las firmas digitales. Es fácil de entender y operar y también es muy popular. El principio es el descrito en el proceso de trabajo anterior.
El algoritmo RSA se basa en un hecho de teoría de números muy simple: es fácil multiplicar dos grandes números primos, pero es extremadamente difícil factorizar sus productos, por lo que el producto puede revelarse como una clave de cifrado.
Implementación del código
Echemos un vistazo a la implementación del código específico a continuación.
import com.google.common.collect.maps; import sun.misc.base64decoder; import sun.misc.base64Encoder; import javax.crypto.cipher; import java.security.*; import java.security.interfaces.rsaprivatekey; import java.security.interfaces.rsapublickey; import java.security.spec.pkcs8EncodedKeySpec; import java.security.spec.x509EncodedKeySpec; import java.util.map; /*** Creado por xiang.li el 2015/3/3. K / *** Definir algoritmo de firma*/ String static final privado Key_rsa_signature = "Md5Withrsa"; / *** Definir algoritmo de clave pública*/ String static final privada Key_rsa_publickey = "rsapublickey"; / *** Definir algoritmo de clave privada*/ String static final privado Key_rsa_privateKey = "rsaprivatekey"; / *** clave de inicialización* @return*/ public static map <String, object> init () {map <string, object> map = null; Pruebe {KeyPairGenerator Generator Generator = KeyPairGenerator.GetInstance (Key_RSA); generador.initialize (1024); Keypair keypair = generador.generateKepair (); // Public Key rsapublickey publickey = (rsapublickey) keypair.getPublic (); // clave privada rsaprivateKey privateKey = (rsaprivatekey) keypair.getPrivate (); // Encapsular la tecla como map map = maps.newhashmap (); map.put (key_rsa_publickey, publickey); map.put (key_rsa_privatekey, privateKey); } Catch (nosuchalgorithMexception e) {E.PrintStackTrace (); } mapa de retorno; } / *** Use la clave privada para generar una firma digital para la información* @param Data Datos cifrados* @param Key privada Key* @return* / public static String Sign (byte [] data, string privateKey) {string str = ""; intente {// descifrar la clave privada codificada byte [] bytes = Decryptbase64 (privateKey); // Construye el objeto PKCS8EncodedKeySpec PKCS8EncodedKeySpec PKCS = nuevo PKCS8EncodedKeySpec (bytes); // El algoritmo de cifrado especificado KeyFactory Factory = KeyFactory.getInstance (Key_RSA); // Obtener el objeto de clave privada Key Key = factory.GeneratePrivate (PKCS); // Use la clave privada para generar una firma digital para la información firma firma = firma.getInstance (key_rsa_signature); firma.initsign (clave); firma.update (datos); str = CiCryptBase64 (firma.sign ()); } catch (Exception e) {E.PrintStackTrace (); } return str; } / *** Verifique la firma digital* @param datos cifrados de datos* @param clave pública clave* @param firma digital firma* @return verify devuelve exitoso, devolución fallida Falso* / public static boolean Verify (byte [] data, string publickey, firma de cadena) {boolean flag = false; intente {// descifrar la clave pública codificada byte [] bytes = Decryptbase64 (public Key); // Construye el objeto X509CodedKeySpec x509CodedKeySpec KeySpec = new x509EncodedKeySpec (bytes); // El algoritmo de cifrado especificado KeyFactory Factory = KeyFactory.getInstance (Key_RSA); // Obtener el objeto de clave pública PublicKey Key = factory.GeneratePublic (KeySpec); // Verifique la firma digital con la firma de la clave pública firma = firma.getInstance (key_rsa_signature); firma.initverify (clave); firma.update (datos); flag = Signature.verify (DecryptBase64 (signo)); } catch (Exception e) {E.PrintStackTrace (); } Bandera de retorno; } / *** clave privada Decrypt* @param datos cifrados datos* @param clave privada clave* @return* / public static byte [] DecryptbyPrivateKey (byte [] data, clave de cadena) {byte [] resultado = null; intente {// descifrar la clave privada byte [] bytes = Decryptbase64 (clave); // Obtenga la clave privada PKCS8EncodedKeySpec KeySpec = new PKCS8EncodedKeySpec (bytes); KeyFactory factory = keyFactory.getInstance (key_rsa); PrivateKey privateKey = factory.GeneratePrivate (KeySpec); // descifrar el cifrado de datos = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.decrypt_mode, privateKey); resultado = cipher.dofinal (datos); } catch (Exception e) {E.PrintStackTrace (); } resultado de retorno; } / *** Decryción de la clave privada* @param datos cifrados de datos* @param clave pública clave* @return* / public static byte [] DecryptbyPublickey (byte [] data, clave de cadena) {byte [] dult = null; intente {// descifrar la clave pública byte [] bytes = Decryptbase64 (clave); // Obtenga la clave pública X509CodedKeySpec KeySpec = new X509EncodedKeySpec (bytes); KeyFactory factory = keyFactory.getInstance (key_rsa); PublicKey PublicKey = factory.GeneratePublic (KeySpec); // descifrar el cifrado de datos = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.decrypt_mode, public key); resultado = cipher.dofinal (datos); } catch (Exception e) {E.PrintStackTrace (); } resultado de retorno; } / *** Cifrado de clave pública* @Param Data Data para estar encriptados* @param clave pública clave* @return* / public static byte [] ciRyptbyPublickey (byte [] data, clave de cadena) {byte [] resultado = null; intente {byte [] bytes = Decryptbase64 (clave); // Obtenga la clave pública X509CodedKeySpec KeySpec = new X509EncodedKeySpec (bytes); KeyFactory factory = keyFactory.getInstance (key_rsa); PublicKey PublicKey = factory.GeneratePublic (KeySpec); // cifrado datos cifrado = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, public key); resultado = cipher.dofinal (datos); } catch (Exception e) {E.PrintStackTrace (); } resultado de retorno; } / *** Cifrado de clave privada* @param Data para encriptar* @param clave privada Key* @return* / public static byte [] encryptbyprivatekey (byte [] data, clave de cadena) {byte [] resultado = null; intente {byte [] bytes = Decryptbase64 (clave); // Obtenga la clave privada PKCS8EncodedKeySpec KeySpec = new PKCS8EncodedKeySpec (bytes); KeyFactory factory = keyFactory.getInstance (key_rsa); PrivateKey privateKey = factory.GeneratePrivate (KeySpec); // cifrado datos cifrado = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, privateKey); resultado = cipher.dofinal (datos); } catch (Exception e) {E.PrintStackTrace (); } resultado de retorno; } / ** * Obtenga la clave pública * @param map * @return * / public static string getPublicKey (map <string, object> map) {string str = ""; intente {key key = (key) map.get (key_rsa_publickey); str = CiCryptBase64 (key.getEncoded ()); } catch (Exception e) {E.PrintStackTrace (); } return str; } / ** * Obtenga la clave privada * @param map * @return * / public static string getPrivateKey (map <string, object> map) {string str = ""; intente {key key = (key) map.get (key_rsa_privatekey); str = CiCryptBase64 (key.getEncoded ()); } catch (Exception e) {E.PrintStackTrace (); } return str; } / *** Base64 Decrypt* @param Cadena clave que debe descifrar* @return byte array* @throws excepción* / public static byte [] DECRYPTBASE64 (clave de cadena) lanza excepción {return (nueva base64Decoder ()). DecodeBuffer (clave); } / *** Base64 Cifrado* @param Key Byte Matray que debe encriptar* @return String* @throws Exception* / public static String encryptbase64 (byte [] key) lanza excepción {return (new base64Encoder ()). CodeBuffer (clave); } / *** Método de prueba* @param args* / public static void main (string [] args) {string privateKey = ""; String PublicKey = ""; // Generar la clave pública MAP de clave privada <String, Object> MAP = init (); publickey = getPublicKey (mapa); privateKey = getPrivateKey (mapa); System.out.println ("Public Key: /N /R" + PublicKey); System.out.println ("Key privado: /n /r" + privateKey); System.out.println("Public key encryption------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- "; byte[] encWord = CiCryPtByPublicKey (Word.getBytes (), public Key); encryption---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- cifryptbyprivatekey (inglés.getbytes (), privatekey); String decenglish = new String (DecryptByPublicKey (Encenglish, PublicKey)); System.out.println ("Antes de cifrado:" + inglés + "/n/r" + "después del descifrado:" + decenglish); System.out.println ("Firma de verificación de clave de clave de clave privada de clave pública"); // Generar firma de cadena firma = signo (encenglish, privateKey); System.out.println ("firma:/r" + signo); // verificar el estado booleano de firma = verificar (encenglish, public key, signo); System.out.println ("Status:/R" + Status); }} Cifrar y descifrar resultados
Conclusión
De hecho, se puede describir un proceso aparentemente complejo en una oración: utilizando el cifrado de clave pública y el descifrado de la clave privada, una transferencia de datos de la parte B a la parte A se completa, a través del cifrado de clave privada y el descifrado de clave pública, y al mismo tiempo, la firma de clave privada y la firma de verificación de clave pública, una transferencia de datos y verificación de la parte de la parte A a la parte B se completan, y dos transferencias de datos completan un conjunto completo de interacciones de datos de datos.
La aparición de algoritmos de cifrado asimétricos es resolver el problema de encriptar y descifrar solo una clave. Mientras se pierda o divulgue esta clave, los datos cifrados serán fácilmente atacados. Al mismo tiempo, se debe precisamente a la aparición de algoritmos de cifrado asimétricos que se obtienen las firmas digitales posteriores, los certificados digitales, etc.
Bien, detengamos aquí hoy. El siguiente artículo continúa con cifrado asimétrico. En cuanto a cuál, lo sabré en ese momento. Mantenlo en secreto aquí primero