Sinto que já faz muito tempo desde a última vez que escrevi um blog. Deixe -me reclamar primeiro. Este mês, a empresa trabalha horas extras, publicando e lançando a publicação, e novos projetos são muito apertados, então não vou dizer muito sobre os específicos. Hoje, é realmente importante falar sobre criptografia assimétrica. A criptografia assimétrica é indispensável em nossas vidas diárias.
conceito
Antes de falar sobre a RSA, vamos primeiro falar sobre o que é criptografia assimétrica. Ao falar sobre criptografia simétrica, já foi dito que os algoritmos de criptografia simétrica usam a mesma chave secreta ao criptografar e descriptografar, e ambas as partes para criptografar e descriptografar devem usar a mesma chave para se comunicar normalmente. A criptografia assimétrica não é o caso. O algoritmo de criptografia assimétrica exige duas chaves para criptografar e descriptografar, a chave pública e a chave privada.
Uma coisa a observar é que a chave pública e a chave privada devem ser um par. Se os dados forem criptografados com a chave pública, apenas a chave privada correspondente poderá ser descriptografada e vice -versa. Como a criptografia e descriptografia usam duas teclas diferentes, esse algoritmo é chamado de algoritmo de criptografia assimétrica.
Processo de trabalho
Conforme mostrado na figura abaixo, os dados são transmitidos usando a criptografia assimétrica.
Os principais algoritmos utilizados na criptografia assimétrica incluem: RSA, Elgamal, algoritmo de mochila, Rabin, DH, ECC (algoritmo de criptografia de curva elípticos), etc. Hoje, apresentaremos principalmente a RSA. Quanto a outros algoritmos, escolheremos alguns para apresentá -los mais tarde.
RSA
De fato, a RSA apareceu já em 1978, e foi o primeiro algoritmo que pode ser usado para criptografia de dados e assinaturas digitais. É fácil de entender e operar e também é muito popular. O princípio é como descrito no processo de trabalho acima.
O algoritmo RSA é baseado em um fato muito simples da teoria do número: é fácil multiplicar dois grandes números primários, mas é extremamente difícil fatorar seus produtos, para que o produto possa ser divulgado como uma chave de criptografia.
Implementação de código
Vamos dar uma olhada na implementação específica de código abaixo.
importar com.google.common.collect.maps; importar sun.misc.base64decoder; importar sun.misc.base64Encoder; importar javax.crypto.cipher; importar java.security.*; importar java.security.interfaces.rsaprivateKey; importar java.security.interfaces.rsapublickey; importar java.security.spec.pkcs8encodedkeyspec; importar java.security.spec.x509EncodedKeyspec; importar java.util.map; /*** Criado por xiang.li em 2015/3/3. * RSA CLASSE CLASSE CRIPTIÇÃO E DESCRIPTIONAÇÃO*/ Public Class RSA {/ *** Definir Método de Criptografia*/ String estática final privada key_rsa = "RSA"; / *** Definir algoritmo de assinatura*/ String estática final privada key_rsa_signature = "md5withrsa"; / *** Definir algoritmo de chave pública*/ String estática final privada key_rsa_publickey = "rsapublickey"; / *** Definir algoritmo de chave privada*/ String estática final privada key_rsa_privateKey = "rsaprivateKey"; / *** Chave de inicialização* @return*/ public static map <string, object> init () {map <string, object> map = null; tente {gerador de keyyairGenerator gerador = keypairgenerator.getInstance (key_rsa); generator.initialize (1024); Teclado do teclado = gerador.GeraReKeyypair (); // Public Key RsapublicKey PublicKey = (RsapublicKey) KEYYPAIR.GETPUBLIC (); // chave privada rsaprivateKey privateKey = (rsaprivateKey) keypair.getprivate (); // encapsula a chave como mapa mapa = maps.newhashmap (); map.put (key_rsa_publickey, publicKey); map.put (key_rsa_privateKey, privateKey); } catch (nosuchalgorithMexception e) {e.printStackTrace (); } mapa de retorno; } / *** Use a chave privada para gerar uma assinatura digital para as informações* @Param Data Encrypted Data* @param private Key Private* @return* / public static string sinal (byte [] dados, string privateKey) {string str = ""; tente {// descriptografar a chave privada codificada byte [] bytes = decryptBase64 (privateKey); // Construa o objeto PKCS8ENCODEDKEYSPEC PKCS8ENCODEDKEYSPEC PKCS = novo PKCS8ENCODEDKEYSPEC (bytes); // O algoritmo de criptografia especificado Factory KeyFactory = keyFactory.getInstance (key_rsa); // obtenha o objeto privado privateKey key = factory.GeReRePrivate (PKCS); // Use a chave privada para gerar uma assinatura digital para assinatura de informação assinatura = assinatura.getInstance (key_rsa_signature); assinatura.initsign (chave); assinatura.Update (dados); str = EncryptBase64 (Signature.sign ()); } catch (Exceção e) {e.printStackTrace (); } retornar str; } / *** Verifique a assinatura digital* @Param Data Data criptografado* @param publicKey Public Key* @param assinando assinatura digital* @return Verifique se o retorno bem -sucedido retorna, falha retornam false* / public static boolean verify (byte [] dados, string publicKey, string signo) {sinalizador boolean = false; tente {// descriptografar a chave pública codificada byte [] bytes = decryptBase64 (publicKey); // Construa o objeto X509ENCODEDKEYSPEC X509ENCODEDKEYSPEC KEYSPEC = novo x509ENCODEDKEYSPEC (bytes); // O algoritmo de criptografia especificado Factory KeyFactory = keyFactory.getInstance (key_rsa); // Obtenha o objeto Public Key PublicKey key = Factory.GeraRatePublic (KEYSPEC); // Verifique a assinatura digital com a assinatura da chave pública = assinatura.getInstance (key_rsa_signature); assinatura.initVerify (chave); assinatura.Update (dados); sinalizador = assinatura.Verify (decryptBase64 (sinal)); } catch (Exceção e) {e.printStackTrace (); } retornar sinalizador; } / *** Chave privada descriptografar* @param dados de dados criptografados* @param chave privada chave* @return* / public static byte [] decryptbyprivateKey (byte [] dados, chave de string) {byte [] resultado = null; tente {// descriptografar o byte de chave privada [] bytes = decryptBase64 (chave); // Obtenha a chave privada PKCS8ENCODEDKEYSPEC KEYSPEC = novo PKCS8ENCODEDKEYSPEC (Bytes); Keyfactory factory = keyfactory.getInstance (key_rsa); PrivateKey PrivateKey = Factory.GeneratePrivate (Keyspec); // descriptografar os dados cifra cifra = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.decrypt_mode, privateKey); resultado = cipher.Dofinal (dados); } catch (Exceção e) {e.printStackTrace (); } resultado de retorno; } / *** Decriptografia de chave privada* @Param Data Data criptografada* @param chave pública* @return* / public static byte [] decryptbypublickey (byte [] dados, chave de string) {byte [] resultado = null; tente {// descriptografar o byte de chave pública [] bytes = decryptBase64 (chave); // obtenha a chave pública x509encodedkeyspec Keyspec = novo x509EncodedKeyspec (bytes); Keyfactory factory = keyfactory.getInstance (key_rsa); PublicKey PublicKey = Factory.GeraRatePublic (Keyspec); // descriptografar os dados cifra cifra = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.decrypt_mode, publicKey); resultado = cipher.Dofinal (dados); } catch (Exceção e) {e.printStackTrace (); } resultado de retorno; } / *** Criptografia de chave pública* @param dados de dados a serem criptografados* @param key public key* @return* / public static byte [] EncryptbypublicKey (byte [] dados, chave de string) {byte [] resultado = null; tente {byte [] bytes = decryptBase64 (chave); // obtenha a chave pública x509encodedkeyspec Keyspec = novo x509EncodedKeyspec (bytes); Keyfactory factory = keyfactory.getInstance (key_rsa); PublicKey PublicKey = Factory.GeraRatePublic (Keyspec); // criptografar dados cifra cifra = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, publicKey); resultado = cipher.Dofinal (dados); } catch (Exceção e) {e.printStackTrace (); } resultado de retorno; } / *** Criptografia de chave privada* @param dados a serem criptografados* @param chave privada* @return* / public static byte [] EncryptbyPrivateKey (byte [] dados, chave de string) {byte [] resultado = null; tente {byte [] bytes = decryptBase64 (chave); // obtenha a chave privada PKCS8ENCODEDKEYSPEC KEYSPEC = novo PKCS8ENCODEDKEYSPEC (bytes); Keyfactory factory = keyfactory.getInstance (key_rsa); PrivateKey PrivateKey = Factory.GeneratePrivate (Keyspec); // criptografar dados cifra cifra = cipher.getInstance (factory.getalgorithm ()); cipher.init (cipher.encrypt_mode, privateKey); resultado = cipher.Dofinal (dados); } catch (Exceção e) {e.printStackTrace (); } resultado de retorno; } / ** * Obtenha a chave pública * @param mapa * @return * / public static string getPublicKey (map <string, object> map) {string str = ""; tente {key key = (key) map.get (key_rsa_publickey); str = EncryptBase64 (key.getEncoded ()); } catch (Exceção e) {e.printStackTrace (); } retornar str; } / ** * Obtenha a chave privada * @param mapa * @return * / public static string getPrivateKey (map <string, object> map) {string str = ""; tente {key key = (key) map.get (key_rsa_privateKey); str = EncryptBase64 (key.getEncoded ()); } catch (Exceção e) {e.printStackTrace (); } retornar str; } / *** base64 descriptografar* @Param Key String que precisa ser descriptografada* @return byte Array* @throws Exceção* / public static byte [] decryptBase64 (key string) lança exceção {return (new Base64Decoder ()). DecodeBuffer (key); } / *** base64 Criptografia* @param key byte matriz que precisa ser criptografada* @return string* @throws Exceção* / public static string EncryptBase64 (byte [] key) lança exceção {return (new Base64Encoder ()). EncodeBuffer (key); } / *** Método de teste* @param args* / public static void main (string [] args) {string privateKey = ""; String publicKey = ""; // gerar o mapa de chave privada de chave pública <string, objeto> map = init (); publicKey = getPublicKey (mapa); privateKey = getPrivateKey (mapa); System.out.println ("Public Key: /N /R" + PublicKey); System.out.println ("private chave: /n /r" + privateKey); System.out.println ("Criptografia de chave pública ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EncryptbypublicKey (Word.Getbytes (), PublicKey); encryption---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EncryptbyPrivateKey (inglês.getbytes (), privateKey); String Decengish = new String (DecryptBypublicKey (Encenglish, PublicKey)); System.out.println ("Antes da criptografia:" + inglês + "/n/r" + "após descriptografia:" + decenglish); System.out.println ("Assinatura de verificação-chave da assinatura de chave privada"); // gerar sinal de sequência de assinatura = sinal (Encenglish, privateKey); System.out.println ("assinatura:/r" + sinal); // Verifique o status booleano da assinatura = Verifique (Encenglish, PublicKey, Sign); System.out.println ("status:/r" + status); }} Criptografar e descriptografar resultados
Conclusão
De fato, um processo aparentemente complexo pode ser descrito em uma frase: usando a criptografia de chave pública e a descriptografia de chave privada, uma transferência de dados da parte B para a parte A é concluída, por meio de criptografia de chave privada e decripção de chave pública e, ao mesmo tempo, através de dados, através de uma assinatura de chaves e dois dados, uma verificação transferida e verificação de uma parte para a parte B é concluída.
O surgimento de algoritmos de criptografia assimétrica é resolver o problema de criptografar e descriptografar apenas uma chave. Enquanto essa chave for perdida ou divulgada, os dados criptografados serão facilmente atacados. Ao mesmo tempo, é precisamente devido ao surgimento de algoritmos de criptografia assimétrica que as assinaturas digitais subsequentes, certificados digitais etc. são obtidos.
Ok, vamos parar por aqui hoje. O próximo artigo continua criptografia assimétrica. Quanto a qual, vou saber naquele momento. Mantenha -o em segredo aqui primeiro