Criptografia e descriptografia de dados usando a chave pública e privada da RSA gerada pelo OpenSSL em Java
O que é RSA: O algoritmo de criptografia de chave pública da RSA foi desenvolvida em 1977 por Ron Rivest, Adi Shamirh e Len Adleman no (Massachusetts Institute of Technology). A nomeação da RSA vem dos nomes que desenvolvem os três. A RSA é o algoritmo de criptografia de chave pública mais influente no momento. Ele é capaz de resistir a todos os ataques criptográficos conhecidos até agora e foi recomendado pela ISO como um padrão de criptografia de dados -chave públicos. Atualmente, esse método de criptografia é amplamente utilizado em bancos on -line, assinaturas digitais e outras ocasiões. O algoritmo RSA é baseado em um fato muito simples da teoria do número: é muito fácil multiplicar dois grandes números primários, mas foi extremamente difícil fatorar o produto naquele momento, para que o produto possa ser divulgado como uma chave de criptografia.
O que é OpenSSL: numerosos algoritmos criptográficos, padrões de infraestrutura de chave pública e protocolos SSL, e talvez esses recursos interessantes lhe dêem a idéia de implementar todos esses algoritmos e padrões. Nesse caso, ao expressar sua admiração, ainda não posso deixar de lembrá -lo: este é um processo assustador. Este trabalho não é mais tão simples quanto ler algumas monografias de criptografia e documentos de protocolo, mas entender todos os detalhes de todos esses algoritmos, padrões e documentos de protocolo e implementar essas definições e processos um por um com caracteres C com os quais você pode estar familiarizado. Não sabemos quanto tempo você precisará para fazer esse trabalho divertido e terrível, mas certamente não é um ou dois anos. O OpenSSL é uma coleção de algoritmos que combina muitos algoritmos de segurança, escritos por dois grandes homens, Eric A. Young e Tim J. Hudson, desde 1995. Por meio de comandos ou bibliotecas de desenvolvimento, podemos facilmente implementar aplicativos de algoritmo público padrão.
Um dos meus hipotéticos de aplicação:
Com a popularidade da Internet móvel, os aplicativos desenvolvidos para dispositivos móveis estão surgindo um após o outro. Esses aplicativos são frequentemente acompanhados pelas funções de registro do usuário e verificação de senha. Existem perigos ocultos na segurança na "transmissão de rede" e "acesso ao log de aplicativos". As senhas são dados confidenciais para os usuários e os desenvolvedores precisam tomar as precauções de segurança antes que o aplicativo seja iniciado. O manuseio inadequado pode causar problemas como ataques maliciosos de concorrentes de negócios e litígios por parceiros de terceiros.
Embora os algoritmos RSA tenham muitos benefícios, não há exemplo completo na Internet para ilustrar como operá -los. Deixe -me apresentá -lo abaixo:
1. Use OpenSSL para gerar chaves privadas e públicas
Estou usando um sistema Linux e tenho o pacote OpenSSL instalado. Verifique se o OpenSSL está instalado em sua máquina. As informações a seguir devem aparecer ao executar o comando:
[root@chaijunkun ~]# openssl version -a OpenSSL 1.0.0-fips 29 Mar 2010 built on: Wed Jan 25 02:17:15 GMT 2012 platform: linux-x86_64 options: bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector - -param = ssp -buffer -size = 4 -m64 -mtune = genérico -wa, -noexecstack -dmd32_reg_t = int -dopenssl_ia32_ssse2 -donssl_bn_asm_mont -dsha1_asm -ms56_asm -dsha_dsha_asm_mont -dsha1_asm56_asm -dsha -Dwhirlpool_asm openssldir: "/etc/pki/tls" motores: aesni dinâmica
Primeiro gerar a chave privada:
[root@chaijunkun ~]# openssl genrsa -out rsa_private_key.pem 1024 gerando chave privada rsa, módulo de 1024 bits de comprimento .................. ++++++ .. ++++++++ e é 65537 (0x10001)
Este comando permite que o OpenSSL gere uma chave privada aleatoriamente e o comprimento da criptografia é de 1024 bits. O comprimento criptografado refere -se ao limite teórico do comprimento máximo permitido de "informações criptografadas", ou seja, o limite de comprimento do texto simples. À medida que esse parâmetro aumenta (por exemplo, 2048), o comprimento de texto simples permitido também aumentará, mas também causará um rápido aumento na complexidade da computação. O comprimento recomendado é de 1024 bits (128 bytes).
Vamos dar uma olhada no conteúdo da chave privada:
[root@chaijunkun ~]# cat rsa_private_key.pem ----- Comece a chave privada rsa ----- miicwwibaakbgqchdzcjw/rwgfwnxunbkp7/4e8w/umxx2jk6qeen69t6n2r1i/l 4 mcyDT1xr/T2AHGOiXNQ5V8W4iCaaeNawi7aJaRhtVx1uOH/2U378fscEESEG8XDq ll0GCfB1/TjKI2aitVSzXOtRs8kYgGU78f7VmDNgXIlk3gdhnzh+uoEQywIDAQAB AOGAAEKK76CSSP7K90MWYWP18GHLZRU+VEÍCULO PHU2TE7vi4LDkw9df1fya+DScSLnaDAUN3OHB5jqGL+Ls5ECQQDUfuxXN3uqGYKk znrKj0j6pY27HRfROMeHgxbjnnApCQ71SzjqAM77R3wIlKfh935OIV0aQC4jQRB4 ihysll9lakeawgh4jxxxxEiaUfMSGJOI3qpjqgvumkx0W96MCCwv3fSew7w1/msi Sutkjp5bbvjfvfwfmahyljdp7w+nebwkbwjaybz/eb5naa EgPLwsjI/mkhrb484xZ2VyuICIwYwNmfXpA3yDgQWsKqdgy3Rrl9lV8/AQJAcjLi IfigUr++nJxA8C4Xy0CZSoBJ76k710wdE1MPGr5WgQF1t+P+bCPjVAdYZm4Mkyv0 /ybxbd16qvixjvnt6qjabli6zx9gyRWNU6akpDaHd8qjwonnnfnlqhue4wepevKM Cysg+ibs2ggsxntrzlwjlfx7vhmpstc8ynmx1kfw ==-ENDEN-END RSA RSA RSA RSA RSA
O conteúdo são todos caracteres ASCII padrão, com marcas óbvias no início e nas linhas finais, e os dados de chave privada reais são caracteres irregulares no meio.
Suplementar em 24 de março de 2015: O arquivo -chave acabará por armazenar os dados através da codificação BASE64. Você pode ver que o comprimento de cada linha do conteúdo do arquivo de chave acima é muito regular. Isso se deve às disposições no RFC2045: o fluxo de saída codificado deve ser representado em linhas de não mais que 76 caracteres cada. Ou seja, os dados codificados pela Base64 não excederão 76 caracteres por linha e precisam ser divididos por linha para obter dados ultra-longos.
Em seguida, gerar a chave pública com base na chave privada:
[root@chaijunkun ~]# openSSL rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout writing rsa chave
Vamos dar uma olhada no conteúdo da chave pública:
[root@chaijunkun ~]# cat rsa_public_ley.pem ----- Comece a chave pública ----- migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqchdzcjw/rwgfwnxunbkp7/4e8w /Umxx2jk6qeen69t6n2r1i/lmcydt1xr/t2ahgoixnq5v8w4icaaenawi7ajarht vx1UOH/2U378FSCEESEG8XDQLL0GCF1/tjki2aitvszxotrs8gg8Ging7GFMFMFM1G7KGROGNG7GROGTRS8GLIGNG7GPTRS8GLIGNGRONGPTRS8GLIRSTRS8GTRS8GLIGNG7GPTRS8GPROGRONGRONGPTRS8TRS8GLIGNG7GPTRS8GLIRSTRS8GLIGNS8GPROMBLO Xilk3gdhnzh+uoeqywidaqab ----
Neste momento, a chave privada não pode ser usada diretamente, portanto, é necessária a codificação do PKCS#8:
[root@chaijunkun ~]# openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
O comando indica que o arquivo de chave privada de entrada é rsa_private_key.pem, e o arquivo de chave privado de saída é PKCS8_RSA_PRIVATE_KEY.PEM, e nenhuma criptografia secundária é usada (-nocrypt)
Vamos dar uma olhada se o arquivo de chave privada codificado é diferente do arquivo de chave privada anterior:
[root@chaijunkun ~]# cat pkcs8_rsa_private_key.pem
-----BEGIN PRIVATE KEY----- MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKEPNyPD+taAXCfG 6dsqnv/h7zD9SZfHaOTqoQSfr23o3ZHWL8uZzINPXGv9PYAcY6Jc1DlXxbiIJpp4 1rclTolpgg1xhw44f/ztfvx+xwqriqBxCOQWXQYJ8HX9OMOJZQK1VLNC61GZYRIA ZTVX/TWYM2BCCIWTEB2GFOH6GRDLAGMBAACYBP4QTVOJKTONKY u768SF9P0GlXrtwYuDWjAVue0VhBI9WxMWZTaVafkcP8hxX4QZqPh84td0zjcq3j DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ DvVLOOoAzvtHfAiUp+H3fk4hXRpALiNBEHiIdhIuX2UCQQDCCHiPHFd4gC58yyCM 6Leqkmoa+6YpfRb3oxykLBXcWx7DtbX+ayKy5OQmnkEG+MW8XB8wAdiUl0/tb6cQ FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA 2z9ekdfioBBawqp2dldgux2vxz8BakbyMuiH+kbsv76cnedwlhflqjlkgenvqtvx tb0tuw8avlabaxw34/5si+nub1hMbgytk/t/ipcencexpbwlgo+e3phelgw1hmbgytk/t/ipcencexpbwlgo+e3phelgwlgw1hmbgytk/t/ipcencexpbwlgo+e3phelgo+e3psi+nub1hmbgytk/t/ipcencexpbwlgo+e3s Fae7oaqkmad3xcny6ec180tae57hz6ks+sylkwb4ggzyacxc22vmtyksxhtueamo 1nmlzi2zfUox ----- Tecla privada final ----
Neste ponto, os pares de teclas disponíveis foram gerados. A chave privada usa pkcs8_rsa_private_key.pem, e a chave pública usa rsa_public_key.pem.
Adicionado em 20 de maio de 2014: Recentemente, encontrei a necessidade de criptografia RSA, e a outra parte exigia que eles pudessem usar apenas o arquivo de chave privado que não foi codificado pelo PKCS#8 gerado na primeira etapa. Mais tarde, verifiquei os documentos relevantes e aprendi que o arquivo de chave privado gerado na primeira etapa é o formato PKCS#1. Este formato é realmente suportado por Java, mas eu apenas escrevo mais duas linhas de código:
RsaprivateKeyStructure Asn1PrivKey = nova RsaprivateKeyStructure ((Asn1Sequence) Asn1Sequence.FrombyTearRray (Prikeydata)); RsaprivateKeyspec rSaprivkeyspec = new RsaprivateKeyspec (asn1privkey.getModulus (), asn1privkey.getprivateExponent ()); KeyFactory keyFactory = keyFactory.getInstance ("rsa"); PrivateKey Prikey = keyFactory.GeReReRPrivate (rsaprivkeyspec); Primeiro, leia o arquivo de chave privado do PKCS#1 (observe que você remove o conteúdo do comentário no início do sinal de menos) e use Base64 para decodificar a string de leitura para obter o PrikeyData, que é o parâmetro na primeira linha de código. A última linha recebe a chave privada. Não há diferença no próximo uso.
Referências: https://community.oracle.com/thread/1529240?start=0&tstart=0
2. Escreva o código Java para testá -lo
23 de fevereiro de 2012: O JDK padrão é especificado apenas no JCE (JCE (JCE (Java Cryptography Extension) é um conjunto de pacotes que fornecem estruturas e implementações para a criptografia, geração e negociação e código de autenticação de mensagens (MAC) Allingms. Objetos.) Interfaces, mas as implementações internas precisam ser fornecidas por elas mesmas ou por terceiros. Em outras versões JDK, você pode encontrar a versão correspondente na página de download anterior.
Vamos dar uma olhada no código que implementei:
pacote net.csdn.blog.chaijunkun; importar java.io.bufferedReader; importar java.io.ioException; importar java.io.inputStream; importar java.io.inputStreamReader; importar java.security.InValidKeyException; importar java.security.keyFactory; importar java.security.Keypair; importar java.security.KeypairGenerator; importar java.security.nosuchalgorithMexception; importar java.Security.SecureRandom; importar java.security.interfaces.rsaprivateKey; importar java.security.interfaces.rsapublickey; importar java.security.spec.invalidKeyspecException; importar java.security.spec.pkcs8encodedkeyspec; importar java.security.spec.x509EncodedKeyspec; importar javax.crypto.badpaddingException; importar javax.crypto.cipher; importar javax.crypto.illegalblocksizeException; importar javax.crypto.nosuchpaddingException; importar org.bouncycastle.jce.provider.bouncycastleprovider; importar sun.misc.base64decoder; public class Rsaencrypt {private Static final String default_public_key = "migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqchdzcjw/rwgfwnxunbkp7/4e8w" + "/r" + + "/Umxx2jk6qeen69t6n2r1i/lmcydt1xr/t2ahgoixnq5v8w4icaaenawi7ajarht" + "/r" + "vx1UoH/2u378fsceeseg8xdqll0gcfb1/tjki248FM8TiSTEN8M8TIM8TIM8TIRATIRATIRATIMATIMATIMENTE "/r" + "xilk3gdhnzh + uoeqywidaqab" + "/r"; String final de estática privada default_private_key = "miicdqibadanbgkqhkig9w0baqefaascal8wggjbageaoogbakepnypd + taaxcfg" + "/r" + "6DSQNV/H7ZD9SZFHAOTQOQSFR23O3ZHWL8UZZINPXGV9PYACY6JC1DLXXBIIJPP4" + "/R" + "1rcltolpgg1xhw44f/ztfvx + xwqriqbxcoqwxqyj8hx9omojzqk1vlnc61gzyria" + "/r" + "ZTVX/TWYM2BCIWTEB2GFOH66GRDLAGMBAAECGYBP4QTVOJKYNUT3SBDJY/XWAETM" + "/R" "U768SF9P0GLXRTWYUDWJAVUE0VHBI9WXMWZTAVAFKCP8HXX4QZQPH84TD0ZJCQ3J" + "/R" + "DLOegAFJkIorGzq5FyK7ydBoU1TLjFV459c8dTZMTu+LgsOTD11/V/Jr4NJxIudo" + "/r" + "MBQ3c4cHmOoYv4uzkQJBANR+7Fc3e6oZgqTOesqPSPqljbsdF9E4x4eDFuOecCkJ" + "/r" + "dvvlooozvthfaiup + h3fk4hxrpalinbehiidhiux2ucqqdcchiphfd4gc58yycm" + "/r" + "6Leqkmoa+6ypfrb3oxyklbxcwx7dtbx+ayky5oqmnkeg+mw8xb8wadiul0/tb6cq"+"/r"+ "FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "/r" + "2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "/r" + "tb0tuw8avlabaxw34/5si + nub1hmbytk/t/ifceptxpbwlgo + e3pakagwlpnh0zh" + "/r" + "fae7oaqkmad3xcny6ec180tae57hz6ks + syLATHATHATSTRATSTENCTENGZ180TAE57HZ6KS + + "/r" + "1nmlzi2zfUox" + "/r"; / *** Chave privada*/ Private RsaprivateKey PrivateKey; / *** Public Key*/ Private RsapublicKey PublicKey; / *** Conjunto privado como string*/ private estático final char [] hex_char = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' f '; / *** Obtenha a chave privada* @return Objeto de chave privada atual*/ public rsaprivateKeykey getPrivateKey () {return privateKey; } / *** Obtenha a chave pública* @return Public Key Object* / public rsapublicKey getPublicKey () {return publicKey; } / *** par de teclas geradas aleatoriamente* / public void genkeypair () {keypairgenerator keyypairgen = null; tente {keypairGen = keypairGenerator.getInstance ("rsa"); } catch (nosuchalgorithMexception e) {e.printStackTrace (); } keypairgen.initialize (1024, new SecureRandom ()); Teclado do teclado = keypairgen.gereateKeypair (); this.privateKey = (rsaprivateKey) keypair.getPrivate (); this.publicKey = (RSAPublicKey) Keypair.getPublic (); } / *** Carregue a tecla pública do fluxo de entrada no arquivo* @param no fluxo de entrada de chave pública* @THOWSOWS Exceção de exceção gerada ao carregar a chave pública* / public void loadPublicKey (inputStream in) lança exceção {try {buffarreder Br = new BufferReader (new inputStrreader (in)); String readLine = null; Stringbuilder sb = new stringbuilder (); while ((readLine = Br.readline ())! = null) {if (readLine.Charat (0) == '-') {continuação; } else {sb.append (readline); sb.append ('/r'); }} loadPublicKey (sb.toString ()); } catch (ioexception e) {lança nova exceção ("erro de leitura de fluxo de dados públicos -chave"); } catch (nullPointerException e) {lança nova exceção ("o fluxo de entrada da chave pública está vazia"); }} / *** Carregue a tecla pública de uma string* @param publicKeystr Public Data String* @Throws Exceção de exceção gerada ao carregar a chave pública* / public void loadPublicKey (string publicKeystr) lança exceção {tente {base64decoder base64decoder = novo base64decer (); byte [] buffer = base64Decoder.DecodeBuffer (publicKeystr); KeyFactory keyFactory = keyFactory.getInstance ("rsa"); X509EncodedKeyspec Keyspec = novo x509EncodedKeyspec (buffer); this.publicKey = (RSAPublicKey) keyFactory.GeneratePublic (Keyspec); } catch (nosuchalgorithMexception e) {lança nova exceção ("algoritmo de nada"); } catch (invalidKeyspecException e) {lançar nova exceção ("chave pública ilegal"); } catch (ioexception e) {lança nova exceção ("Erro de leitura de conteúdo de dados públicos de chaves public"); } catch (nullPointerException e) {lança a nova exceção ("os dados públicos -chave estão vazios"); }} / *** Carregue a chave privada do arquivo* @param keyfilename nome privado Nome do arquivo* @return Se ele é bem -sucedido* @THOWSOWS Exceção* / public void loadPrivateKey (inputStream in) lança exceção {try {bufferreder Br = new BufferReader (new InputStradeer (in)); String readLine = null; Stringbuilder sb = new stringbuilder (); while ((readLine = Br.readline ())! = null) {if (readLine.Charat (0) == '-') {continuação; } else {sb.append (readline); sb.append ('/r'); }} loadPrivateKey (sb.toString ()); } catch (ioexception e) {lança nova exceção ("erro de leitura de dados de chave privada"); } catch (nullPointerException e) {lança nova exceção ("fluxo de entrada de chave privada está vazia"); }} public void loadPrivateKey (String privateKeystr) lança exceção {try {base64Decoder base64Decoder = new Base64Decoder (); byte [] buffer = base64Decoder.DecodeBuffer (privateKeystr); PKCS8ENCODEDKEYSPEC KEYSPEC = novo PKCS8ENCODEDKEYSPEC (buffer); KeyFactory keyFactory = keyFactory.getInstance ("rsa"); this.privateKey = ((rsaPrivateKey) keyFactory.GeReReRPrivate (Keyspec); } catch (nosuchalgorithMexception e) {lança nova exceção ("nada este algoritmo"); } catch (invalidKeyspecException e) {lançar nova exceção ("chave privada ilegal"); } catch (ioexception e) {lança nova exceção ("Erro de leitura de conteúdo de dados de chave privada"); } catch (nullPointerException e) {lança nova exceção ("dados de chave privada estão vazios"); }} / *** Processo de criptografia* @Param PublicKey Public Key* @Param PlainTextData Dados de texto simples* @return* @throws Informações de exceção de exceção durante o processo de criptografia* / public byte [] Encrypt (RsapublicKey PublicKey, Byte [] PlainTextData) THROWS Exception (se (PublicKey === 9) } Cifra cifra = null; tente {cipher = cipher.getInstance ("rsa", novo bouncycastleprovider ()); cipher.init (cipher.encrypt_mode, publicKey); byte [] output = cipher.Dofinal (PlainTextData); saída de retorno; } catch (nosuchalgorithMexception e) {lança nova exceção ("algoritmo de criptografia nada"); } catch (nosuchpaddingException e) {e.printStackTrace (); retornar nulo; } catch (invalidkeyexception e) {lança nova exceção ("a chave pública de criptografia é ilegal, verifique"); } catch (ilegalBlockSizeException e) {lançar nova exceção ("o comprimento do PlackText é ilegal"); } catch (badpaddingException e) {lança nova exceção ("os dados do placktext estão corrompidos"); }} / *** Processo de decepção* @Param PrivateKey Private Key* @param cipherdata cipherText Dados* @return linetext* @throws Informações de exceção de exceção durante o processo de descriptografia* / public byte [] deceptt (RsaPrivateKey PrivateKey, Byte [] cipherdatt) (] Excepctompt (Ift. Por favor, defina "); } Cifra cifra = null; tente {cipher = cipher.getInstance ("rsa", novo bouncycastleprovider ()); cipher.init (cipher.decrypt_mode, privateKey); byte [] output = cipher.dofinal (cipherdata); saída de retorno; } catch (nosuchalgorithMexception e) {lança nova exceção ("Algoritmo de descriptografia de nada"); } catch (nosuchpaddingException e) {e.printStackTrace (); retornar nulo; } catch (invalidkeyexception e) {lança nova exceção ("A chave privada de descriptografia é ilegal, verifique"); } catch (ilegalBlockSizeException e) {lançar uma nova exceção ("o comprimento do Cryptotext é ilegal"); } catch (badpaddingException e) {lança nova exceção ("os dados do Cryptotext estão corrompidos"); }} / *** Dados de byte para string hexadeCimal* @param Dados de entrada dados* @return hexadecimal conteúdo* / public static string bytearraytoString (byte [] data) {stringbuilder stringbuilder = new StringBuilder (); for (int i = 0; i <data.length; i ++) {// retire os quatro dígitos altos do byte como índice para obter o identificador hexadecimal correspondente observe que o shift string string de shift não assinado (hex_char [(dados [i] e 0xf0) >>> 4]); // Retire os quatro bits inferiores do byte como índice para obter o correspondente identificador hexadecimal stringbuilder.append (hex_char [(dados [i] & 0x0f)]); if (i <data.length-1) {stringbuilder.append (''); }} return stringbuilder.toString (); } public static void main (string [] args) {rsaencrypt rsaencrypt = new rsaencrypt (); //rsaencrypt.genKeypair (); // Carregar a chave pública tente {rsaencrypt.loadpublicKey (rsaencrypt.default_public_key); System.out.println ("Carregando a chave pública com sucesso"); } catch (Exceção e) {System.err.println (e.getMessage ()); System.err.println ("Carregando a chave pública falhou"); } // Carregando a chave privada tente {rsaencrypt.loadprivateKey (rsaencrypt.default_private_key); System.out.println ("Carregando a chave privada com sucesso"); } catch (Exceção e) {System.err.println (e.getMessage ()); System.err.println ("carregando falha na chave privada"); } // Test String String EncryptStr = "Test String chaijunkun"; tente {// criptografar byte [] cipher = rsaencrypt.encrypt (rsaencrypt.getpublickey (), cripryptstr.getBytes ()); // descriptografar byte [] PlainText = rsaencrypt.decrypt (rsaencrypt.getprivateKey (), cifra); System.out.println ("Comprimento da CipherText:"+ cipher.length); System.out.println (rsaencrypt.bytearraytoString (cifra)); System.out.println ("Comprimento de texto simples:"+ PLAINTEXT.Length); System.out.println (rsaencrypt.bytearraytoString (PlainText)); System.out.println (new String (PlainText)); } catch (Exceção e) {System.err.println (e.getMessage ()); }}} No código, forneço duas maneiras de carregar chaves públicas e privadas.
Leia por Stream: Adequado para o método de obtenção de InputStream pela ID Indexing Resources em Android Applications;
Leia por string: Conforme mostrado no código, armazene o conteúdo principal por linha em constantes estáticas e importe a chave por tipo de string.
Execute o código acima e as seguintes informações serão exibidas:
1 64 57 C8 E3 46 A7 CE 57 31 AC CD 21 89 89 8F C1 24 C1 22 0C CB 70 6A 0D FA C9 38 80 BA 2E E1 29 02 ED 45 9E 88 E9 23 09 87 AB AB CB A 61 03 3C A1 81 56 A5 A5 A5 230 9f FD 22 87 9E DE B1 F4 E8 B2 Comprimento do texto simples: 22 54 65 73 74 20 53 74 72 69 6e 67 20 63 68 61 69 6a 75 6e 6b 75 6e Test String chaijunkun
Na função principal, comentei "rsaencrypt.genkeypair ()", que é usado para gerar aleatoriamente pares de chaves (apenas gerar, usar, não armazenar). Quando a chave do arquivo não for usada, você pode comentar o código que carrega a chave, ativar esse método ou executar o código.
A diferença entre carregar uma chave pública e carregar uma chave privada é que, quando a chave pública é carregada, x509EncodedKeyspec (instrução-chave codificada por x509) e quando a chave privada é carregada, PKCS8EncodedKeyspec (PKCS#8-8-CHAY Instrução).
Adicionado em 22 de fevereiro de 2012: Durante o desenvolvimento do software Android, verificou -se que o código acima não funcionava corretamente. A principal razão é que a classe Sun.misc.Base64Decoder não existe no pacote de desenvolvimento do Android. Portanto, você precisa procurar o código -fonte do RT.Jar na Internet. Quanto ao código -fonte no SRC.zip do JDK, isso é apenas parte do código -fonte no JDK, e os códigos das classes acima não existem. Depois de pesquisar e adicionar, o código acima funciona bem em aplicativos Android. Isso contém o código correspondente para esta classe. Além disso, essa classe também depende da CeforMatexception, Classes Cestreamexhausted, Classes de Codelos e Definições de Excepção de Caracteres e Excepção.
Adicionado em 23 de fevereiro de 2012: No início, escrevi este artigo para implementar a criptografia e a descriptografia da RSA sem depender de pacotes de terceiros, mas encontrei problemas mais tarde. Como um objeto de cifra deve ser criado no método de criptografia Encrypt e no método descriptografado descriptografar, esse objeto pode obter apenas instâncias através do GetInstance. Existem dois tipos: o primeiro é especificar apenas o algoritmo e não o provedor; O segundo é especificar ambos. No início, o código ainda pode ser executado, mas você descobrirá que o resultado de cada criptografia é diferente. Mais tarde, descobriu -se que a chave pública e privada usada pelo objeto cifra foi gerada aleatoriamente internamente, não a chave pública e privada especificada no código. Estranhamente, esse código que não especifica um provedor pode ser executado através de aplicativos Android e o resultado de cada criptografia é o mesmo. Eu acho que, além de algumas funções de desenvolvimento do sistema no Android SDK, também implementa as funções do JDK. Pode ter fornecido provedores correspondentes em seu próprio JDK, o que faz com que a criptografia resulte o mesmo sempre. Quando adicionei o provedor de bouncycastle, como o código de amostra na Internet, os resultados de cada criptografia são os mesmos.
Obrigado pela leitura, espero que isso possa ajudá -lo. Obrigado pelo seu apoio a este site!