Cifrado de datos y descifrado utilizando la clave pública y privada de RSA generada por OpenSSL en Java
¿Qué es RSA: el algoritmo de cifrado de clave pública de RSA fue desarrollado en 1977 por Ron Rivest, Adi Shamirh y Len Adleman en (Instituto de Tecnología de Massachusetts)? El nombre de RSA proviene de los nombres que desarrollan los tres. RSA es el algoritmo de cifrado de clave pública más influyente en la actualidad. Es capaz de resistir todos los ataques criptográficos conocidos hasta ahora y ha sido recomendado por ISO como un estándar de cifrado de datos de clave pública. En la actualidad, este método de cifrado se usa ampliamente en la banca en línea, las firmas digitales y otras ocasiones. El algoritmo RSA se basa en un hecho de teoría de números muy simple: es muy fácil multiplicar dos grandes números primos, pero fue extremadamente difícil factorizar el producto en ese momento, por lo que el producto puede revelarse como una clave de cifrado.
Lo que es OpenSSL: numerosos algoritmos criptográficos, estándares de infraestructura de clave pública y protocolos SSL, y tal vez estas características interesantes le darán la idea de implementar todos estos algoritmos y estándares. Si es así, mientras expresa su admiración, todavía no puedo evitar recordarle: este es un proceso desalentador. Este trabajo ya no es tan simple como leer algunas monografías de criptografía y documentos de protocolo, sino comprender cada detalle de todos estos algoritmos, estándares y documentos de protocolo, e implementar estas definiciones y procesos uno por uno con caracteres C con los que puede estar familiarizado. No sabemos cuánto tiempo necesitará para hacer este trabajo divertido y terrible, pero ciertamente no es un problema de un año o dos. OpenSSL es una colección de algoritmos que combina muchos algoritmos de seguridad, escritos por dos grandes hombres, Eric A. Young y Tim J. Hudson, desde 1995. A través de comandos o bibliotecas de desarrollo, podemos implementar fácilmente aplicaciones de algoritmos públicos estándar.
Uno de mis antecedentes de aplicaciones hipotéticas:
Con la popularidad de Internet móvil, las aplicaciones desarrolladas para dispositivos móviles están surgiendo uno tras otro. Estas aplicaciones a menudo van acompañadas de funciones de registro de usuarios y verificación de contraseña. Existen peligros ocultos en la seguridad en la "transmisión de red" y el "acceso al registro de aplicaciones". Las contraseñas son datos confidenciales para los usuarios, y los desarrolladores deben tomar precauciones de seguridad antes de que se inicie la aplicación. El manejo inadecuado puede causar problemas como ataques maliciosos por parte de competidores comerciales y litigios por parte de socios externos.
Aunque los algoritmos RSA tienen tantos beneficios, no hay un ejemplo completo en Internet para ilustrar cómo operarlos. Déjame presentarlo a continuación:
1. Use OpenSSL para generar claves privadas y públicas
Estoy usando un sistema Linux y tengo instalado el paquete OpenSSL. Verifique que OpenSSL esté instalado en su máquina. La siguiente información debe aparecer al ejecutar el comando:
[root@chaijunkun ~]# OpenSSL versión -a OpenSSL 1.0.0 -FIPS 29 de marzo de 2010 construido en: mié 25 de enero 02:17:15 GMT 2012 Plataforma: Linux -X86_64 Opciones: Bn (64,64) MD2 (int) RC4 (16X, INT) DES (IDX, CISC, 16, INT) Bloque (IDX) Compilador: GCC -FCC -fx -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 = genic -wa, -NoExecstack -dmd32_reg_t = int -dopenssl_ia32_sse2 -dopenssl_bn_asm_mont -dsha1_asm -dsha256_asm --dsha512_asm --dmd5_asm -Dwhirlpool_asm OpenSslDir: "/etc/pki/tls" motores: Aesni Dynamic
Primero genere la clave privada:
[root@chaijunkun ~]# OpenSSL Genrsa -out RSA_PRIVATE_KEY.PEM 1024 Generación de la clave privada RSA, 1024 Bit Long Modulus ...................... ++++++ .. ++++++++++ E es 65537 (0x10001)
Este comando permite que OpenSSL genere aleatoriamente una clave privada, y la longitud de cifrado es de 1024 bits. La longitud encriptada se refiere al límite teórico del máximo permitido de la longitud de "información cifrada", es decir, el límite de longitud del texto plano. A medida que aumenta este parámetro (por ejemplo, 2048), la longitud de texto sin formato permitido también aumentará, pero también causará un rápido aumento en la complejidad informática. La longitud recomendada es de 1024 bits (128 bytes).
Echemos un vistazo al contenido de la clave privada:
[root@chaijunkun ~]# cat rsa_private_key.pem ----- BEGIN RSA CLAVE PRIVADO ----- miicwwibaakbgqchdzcjw/rwgfwnxunbkp7/4e8w/umxx2jk6een69t6n2r1i/l mcydt1xr/t2ahgoixnq5v8w4icaaenawi7aJarhtvx1Uoh/2u378fsceSeg8xdq ll0gcfb1/tjki2aitvszxotrs8kygu78f7vmdngxilk3gdhnzh+uoeqywidaqab AOGAAEKKK76CSSP7K90MWYWP18GHLZRU+VEHFT9BPV67CGLG1OWFBNTFYQSPVSTFM U2LWN5HD/ICV+EGAJ4FOLXDM43KT4WYZNOABSZCKKXS6URCIU8NQAFNUY4XVEOFX Phu2te7vi4ldkw9df1fya+dscslnadaun3ohb5jqgl+ls5ecqqdufuxxn3uqgykk znrkj0j6py27hrfromhgxbjnnapcq71szjqam77r3wilkfh935oiv0aqc4jqrb4 ihysll9lakeawgh4jxxxeiaufmsgjoi3qpjqgvumkx0w96mcpcwv3fsew7w1/msi sutkjp5bbvjfvfwfmahyljdp7w+nebwkbwjaybz/eb5naza4pxvr5vmcd8cukaj44 Egplwsji/mkhrb484xz2VyUiCiWywnMfxpa3ydgqwskqdgy3rrrl9lv8/aqjacjli ifigu ++ njxa8c4xy0czSobj76k710wde1mpgr5wgqf1t+p+bcpjvadyzm4m4m4m4m4m4m /ybxbd16qvixjvnt6qJabli6zx9gyrwnu6akpdahd8qjwonnnfnlqhue4wepevkm cysg+iBs2ggSxntrzlwjlfx7vhmpqnttc8ynmx1kfw == ------ End rsa privado clave -----
Los contenidos son todos caracteres ASCII estándar, con marcas obvias en el principio y las líneas finales, y los datos clave privados reales son caracteres irregulares en el medio.
Suplementario el 24 de marzo de 2015: El archivo clave eventualmente almacenará los datos a través de la codificación Base64. Puede ver que la longitud de cada línea del contenido de archivo de clave anterior es muy regular. Esto se debe a las disposiciones en RFC2045: la corriente de salida codificada debe representarse en líneas de no más de 76 caracteres cada una. Es decir, los datos codificados por Base64 no excederán los 76 caracteres por línea, y deben dividirse por fila para datos ultra largos.
A continuación, genere la clave pública basada en la clave privada:
[root@chaijunkun ~]# openssl rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout redacción de la tecla RSA
Echemos un vistazo al contenido de la clave pública:
[root@chaijunkun ~]# cat rsa_public_ley.pem ----- BEGIN Public Key ----- migfma0gcsqgsib3dqebaquaaa4gnadcbiqkbgqchdzcjw/rwgfwnxunbkp7/4e8w /UMXX2JK6Qeen69t6n2r1i/lmcydt1xr/t2AHGOIXNQ5V8W4ICAAENAWI7AJARHT VX1UOH/2U378FSCEESEG8XDQLL0GCFB1/TJKI2AITVSZXOTRS8KYGGUGU78F7VMDNG Xilk3gdhnzh+uoeqywidaqab ---- fin de la clave pública ----
En este momento, la clave privada no se puede usar directamente, por lo que se requiere la codificación PKC#8:
[root@chaijunkun ~]# openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
El comando indica que el archivo de clave privada de entrada es RSA_PRIVATE_KEY.PEM, y el archivo de clave privada de salida es PKCS8_RSA_PRIVATE_KEY.PEM, y no se usa cifrado secundario (-nocrypt)
Echemos un vistazo a si el archivo de clave privada codificada es diferente del archivo de clave privada anterior:
[root@chaijunkun ~]# cat PKCS8_RSA_PRIVATE_KEY.PEM
----- Clave privada de comienzo ----- Miicdqibadanbgkqhkig9w0baqefaascal8wggjbageaaaogbakepnypd+taaxcfg 6dsqnv/h7zd9szfhaotqoqsfr23o3zhwl8uzzinpxgv9pyacy6jc1dlxbiiJpp4 1RCLTOLPGG1XHW44F/ZTFVX+XWQRIQBXCOQWXQYJ8HX9OMOJZQK1VLNC61GZYRIA ZTVX/TWYM2BCIWTEB2GFOH66GRDLAGMBAAECGYBP4QTVOJKYNUT3SBDJY/XWAETM U768SF9P0GLXRTWYUDWJAVUE0VHBI9WXMWZTAVAFKCP8HXX4QZQPH84TD0ZJCQ3J DLOEGAFJKIRGZQ5FYK7YDBOU1tlJFV459C8DTZMTU+LGSOTD11/V/JR4NJUDO MBQ3C4CHMOOYV4UZKQJBANR+7FC3E6OZGQTOESQPSPQLJBSDF9E4X4EDFUOECCKJ DVVLOOAZVTHFAIUP+H3FK4HXRPALINBEHIIDHIUX2UCQQDCCHIPHFFD4GC58YYCMM 6leqkMoa+6yPFRB3OXYKLBXCWX7DTBX+AYKY5OQMNKEG+MW8XB8WADIUL0/TB6CQ FARVAKBHVP94HK0DMDINFVHLWYJ3XY4PONGSA8VCYMJ+ASGTVJJJJJK4GIJJA 2z9ekdfioBbawqp2dldGux2VXZ8BAKBYMUIH+KBSV76CnedWlHFLQJLKGENVQTVX TB0TUW8AVLABAXW34/5SI+NUB1HMBGYTK/T/IFCEPXPXPBWLGO+E3PAKAGWLPNH0ZHH Fae7oaqkmad3xcny6ec180tae57hz6ks+sylkwb4ggzyacxc22vmtyksxhtueamo 1nmlzi2zfuox ----- final clave privada -----
En este punto, se han generado los pares de claves disponibles. La clave privada usa pkcs8_rsa_private_key.pem, y la clave pública usa rsa_public_key.pem.
Agregado el 20 de mayo de 2014: recientemente, encontré la necesidad de cifrado RSA, y la otra parte requería que solo pudieran usar el archivo de clave privado que no estaba codificado por los PKC#8 generado en el primer paso. Más tarde, verifiqué los documentos relevantes y aprendí que el archivo de clave privado generado en el primer paso es el formato PKCS#1. Este formato es realmente compatible con Java, pero solo escribo dos líneas de código más:
RsaprivateKeyStructure asn1privkey = nueva rsaprivateKeyStructure ((asn1Sequence) asn1sequence.frombytearray (prikeydata)); RSAPRIVATEKEYSPEC RSAPRIVKEYSPEC = new rsaprivateKeySpec (asn1privkey.getModulus (), asn1privkey.getprivateExPonent ()); KeyFactory KeyFactory = KeyFactory.GetInstance ("RSA"); PrivateKey prikey = keyFactory.GeneratePrivate (rsaprivkeyspec); Primero lea el archivo de clave privada de PKCS#1 (tenga en cuenta que elimina el contenido de comentarios al comienzo del signo menos), y luego usa Base64 para decodificar la cadena de lectura para obtener PrikeYData, que es el parámetro en la primera línea de código. La última línea obtiene la clave privada. No hay diferencia en el próximo uso.
Referencias: https://community.oracle.com/thread/1529240?start=0&tstart=0
2. Escribe código Java para probarlo
23 de febrero de 2012: el JDK estándar solo se especifica en el JCE (JCE (JCE (Java Cryptography Extension) es un conjunto de paquetes que proporcionan marcos e implementaciones para la cifrado, la generación y la negociación de claves, y los algorits de la autenticación de mensajes (MAC). Interfaces, pero las implementaciones internas deben ser proporcionadas por sí mismas o por un tercero. Versiones, puede encontrar la versión correspondiente en la página de descarga anterior.
Echemos un vistazo al código que implementé:
paquete net.csdn.blog.chaijunkun; import java.io.bufferedReader; import java.io.ioException; import java.io.inputstream; import java.io.inputstreamreader; import java.security.invalidkeyException; import java.security.KeyFactory; import java.security.keypair; import java.security.keypairgenerator; import java.security.nosuchalgorithmexception; import java.security.secureurandom; import java.security.interfaces.rsaprivatekey; import java.security.interfaces.rsapublickey; import java.security.spec.invalidkeyspeCexception; import java.security.spec.pkcs8EncodedKeySpec; import java.security.spec.x509EncodedKeySpec; import javax.crypto.badpaddingException; import javax.crypto.cipher; import javax.crypto.illegalblocksizeException; import javax.crypto.nosuchpaddingexception; importar org.bouncycastle.jce.provider.bouncycastleprovider; import sun.misc.base64decoder; Clase pública rsaencrypt {private static final cadena default_public_key = "migfma0gcsqgsib3dqebaquaa4gnadcbiqkbgqchdzcjw/rwgfwnxunbkp7/4e8w" + "/r" + + "/UMXX2JK6QEEN69T6N2R1I/LMCYDT1XR/T2AHGOIXNQ5V8W4ICAAENAWI7AJARHT" + "/R" + "VX1UOH/2U378FSCESEG8XDQLL0GCFB1/TJKI2AITVSZXOTRS8KYGGU78FTNGNG" "/r" + "xilk3gdhnzh + uoeqywidaqab" + "/r"; Cadena final de estática privada default_private_key = "miicdqibadanbgkqhkig9w0baqefaascal8wggjbageaaogbakepnypd + taaxcfg" + "/r" + + "6DSQNV/H7ZD9SZFHAOTQOQSFR23O3ZHWL8UZZINPXGV9PYACY6JC1DLXXBIIJPP4" + "/R" + + "1RCLTOLPGG1XHW44F/ZTFVX + XWQRIQBXCOQWXQYJ8HX9OMOJZQK1VLNC61GZYRIA" + "/R" + + "ZTVX/TWYM2BCIWTEB2GFOH66GRDLAGMBAACGYBP4QTVOJKYNUT3SBDJY/XWAETM" + "/R" + + "U768SF9P0GLXRTWYUDWJAVUE0VHBI9WXMWZTAVAFKCP8HXX4QZQPH84TD0ZJCQ3J" + "/R" + + "Dloegafjkiorgzq5fyk7ydbou1tljfv459c8dtzmtu + lgsotd11/v/jr4njxiudo" + "/r" + "mbq3c4chmoyv4uzkqjbanr + 7fc3e6ozgqtoesqpspqljbsdf9e4eTffffkj" " + "/r" + "dvvloooazvthfaiUp + h3fk4hxrpalinbehiidhiux2ucqqdcchiphfd4gc58yycm" + "/r" + + "6LEQKMOA+6YPFRB3OXYKLBXCWX7DTBX+AYKY5OQMNKEG+MW8XB8WADIUL0/TB6CQ"+"/R"++ "FaRvAkBhvP94Hk0DMDinFVHlWYJ3xy4pongSA8vCyMj+aSGtvjzjFnZXK4gIjBjA" + "/r" + "2Z9ekDfIOBBawqp2DLdGuX2VXz8BAkByMuIh+KBSv76cnEDwLhfLQJlKgEnvqTvX" + "/r" + "TB0TUW8AVLABAXW34/5SI + NUB1HMBGYTK/T/IFCEPXPBWLGO + E3PAKAGWLPNH0ZH" + "/R" + + "FAE7OAQKMAD3XCNY6EC180TAE57HZ6KS + SYLKWB4GGZYACXC22VMTYKSXHTUAMO" + "/R" + "1NMLZI2ZFUOX" + "/R"; / *** clave privada*/ private rsaprivatekey privatekey; / *** clave pública*/ private rsapublickey publickey; / *** Private Set en String*/ private static final char [] hex_char = {'0', '1' ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',' 9 ',' a ',' b ',' c ',' d ',' e ',' f '}; / *** Obtenga la clave privada* @return Objeto de clave privada actual*/ public rsaprivateKey getPrivateKey () {return privateKey; } / *** Obtenga la clave pública* @return Current Public Key Object* / public rsapublickey getPublicKey () {return publickey; } / *** par de teclas generado aleatoriamente* / public void genkEyPair () {keyPairGenerator keyPairGen = null; intente {keyPairGen = keyPairGenerator.getInstance ("rsa"); } Catch (nosuchalgorithMexception e) {E.PrintStackTrace (); } keypairgen.initialize (1024, new SecureRandom ()); KeyPair KeyPair = KeyPairGen.GenerateKeypair (); this.privatekey = (rsaprivatekey) keypair.getPrivate (); this.publickey = (rsapublickey) keypair.getPublic (); } / *** Cargue la clave pública desde la secuencia de entrada en el archivo* @param en la clave de entrada pública secuencia de entrada* @throws Exception Exception Generada al cargar la clave pública* / public void LoadPublicKey (inputStream in) Excepción {try {bufferedReader br = new BufferedReader (New InputStreamReamream (in)); String readline = null; StringBuilder sb = new StringBuilder (); while ((readline = br.readline ())! = null) {if (readline.charat (0) == '-') {continuar; } else {sb.append (readline); sb.append ('/r'); }} LoadPublicKey (sb.ToString ()); } catch (ioException e) {tirar nueva excepción ("Error de lectura de la secuencia de datos de clave pública"); } Catch (NullPointerException e) {Throw New Exception ("El flujo de entrada de clave pública está vacía"); }} / *** Cargue la clave pública desde una cadena* @param public Key Public Key Data String* @throws Excepción de excepción generada al cargar la clave pública* / public void LoadPublicKey (String publickeyStr) arroja excepción {try {base64Decoder base64Decoder = new Base64Decoder (); byte [] buffer = base64Decoder.DecodeBuffer (PublicKeystr); KeyFactory KeyFactory = KeyFactory.GetInstance ("RSA"); X509CodedKeySpec KeySpec = new X509EncodedKeySpec (buffer); this.publickey = (rsapublickey) keyFactory.GeneratePublic (keySpec); } Catch (nosuchalgorithMexception e) {arrojar una nueva excepción ("algoritmo nada"); } Catch (InvalidKeySPeCexception e) {arrojar una nueva excepción ("Public Key Ilegal"); } catch (ioException e) {tirar nueva excepción ("error de lectura de contenido de datos de clave pública"); } Catch (NullPointerException e) {Throw New Exception ("Los datos de clave pública están vacías"); }} / *** Cargue la tecla privada del archivo* @param KeyFileName Nombre del archivo de la clave privada* @return Si es exitosa* @throws excepción* / public void loadPrivateKey (inputStream in) lanza excepción {try {bufferedReader br = new BufferedReader (New InputStreamreamer (in)); String readline = null; StringBuilder sb = new StringBuilder (); while ((readline = br.readline ())! = null) {if (readline.charat (0) == '-') {continuar; } else {sb.append (readline); sb.append ('/r'); }} LoadPrivateKey (sb.ToString ()); } catch (ioException e) {tirar nueva excepción ("error de lectura de datos de clave privada"); } Catch (NullPointerException e) {Throw New Exception ("El flujo de entrada de clave privada está vacía"); }} public void LoadPrivateKey (String privateKeyStr) lanza la excepción {try {base64Decoder base64Decoder = new Base64Decoder (); byte [] buffer = base64Decoder.DecodeBuffer (privateKeystr); PKCS8EncodedKeySpec KeySpec = new PKCS8EncodedKeySpec (buffer); KeyFactory KeyFactory = KeyFactory.GetInstance ("RSA"); this.privatekey = (rsaprivatekey) keyFactory.GeneratePrivate (KeySpec); } Catch (nosuchalgorithmexception e) {tirar nueva excepción ("nada este algoritmo"); } Catch (InvalidKeySpeCexception e) {arrojar una nueva excepción ("Key privada ilegal"); } catch (ioException e) {tirar nueva excepción ("error de lectura de contenido de datos de clave privada"); } Catch (NullPointerException e) {Throw New Exception ("Los datos clave privados están vacíos"); }} / *** Proceso de cifrado* @param PublicKey Public Key* @param data de texto sin texto de formación de asenta* @return* @throws Información de excepción durante el proceso de cifrado* / public byte [] encrypt (rsapublickey publickey, byte [] EntrainsextData) lanza la excepción {si ((null) {Droga New Exception ("CiCryction Key Public Key, por favor, por favor, siente"); } Cifrado cifrado = nulo; intente {cipher = cipher.getInstance ("rsa", new BouncycastleProvider ()); cipher.init (cipher.encrypt_mode, public key); byte [] output = cipher.dofinal (asignextData); salida de retorno; } Catch (nosuchalgorithmexception e) {tirar nueva excepción ("algoritmo de cifrado nohis"); } Catch (nosuchpaddingException e) {E.PrintStackTrace (); regresar nulo; } Catch (InvalidKeyException e) {tirar nueva excepción ("La clave pública de cifrado es ilegal, por favor verifique"); } Catch (ilegalblocksizeException e) {tirar nueva excepción ("La longitud de los pLACKText es ilegal"); } Catch (BadPaddingException e) {Throw New Exception ("Los datos de PlackText están dañados"); }} / *** proceso de descifrado* @param privatekey privado clave* @param cipherdata data de cifrado de texto* @return asignext* @throws Información de excepción de excepción durante el proceso de descifrado* / public byte [] DECRYPT (RSAPRIVATEKEKE KEY KEYKEKE, BYTE [] CIPERDATA). colocar"); } Cifrado cifrado = nulo; intente {cipher = cipher.getInstance ("rsa", new BouncycastleProvider ()); cipher.init (cipher.decrypt_mode, privateKey); byte [] output = cipher.dofinal (cipherdata); salida de retorno; } Catch (nosuchalgorithmexception e) {tirar nueva excepción ("algoritmo de descifrado nada"); } Catch (nosuchpaddingException e) {E.PrintStackTrace (); regresar nulo; } catch (InvalidKeyException e) {tirar nueva excepción ("La clave privada de descifrado es ilegal, por favor verifique"); } Catch (ilegalblocksizeException e) {tirar nueva excepción ("La longitud de criptotexto es ilegal"); } Catch (BadPaddingException e) {Throw New Exception ("Los datos de Cryptotext están dañados"); }} / *** BYTE DATA A HEXADECIMAL STRING* @param Datos de entrada Datos* @return hexadecimal content* / public static string bytearrayToString (byte [] data) {StringBuilder StringBuilder = new StringBuilder (); para (int i = 0; i <data.length; i ++) {// Saque los cuatro dígitos altos del byte como índice para obtener el identificador hexadecimal correspondiente tenga en cuenta que el cambio derecho sin firmar StringBuilder.append (hex_char [(datos [i] & 0xf0) >>> 4]); // Saque los cuatro bits inferiores del byte como índice para obtener el identificador hexadecimal correspondiente StringBuilder.append (hex_char [(datos [i] & 0x0f)]); if (i <data.length-1) {stringBuilder.append (''); }} return stringBuilder.ToString (); } public static void main (string [] args) {rsaencrypt rsaencrypt = new rsaEncrypt (); //rsaencrypt.GenKeyPair (); // Cargue la clave pública Try {rsaencrypt.loadPublicKey (rsaencrypt.default_public_key); System.out.println ("Cargando la clave pública con éxito"); } catch (excepción e) {system.err.println (e.getMessage ()); System.err.println ("Cargar la clave pública falló"); } // Cargando la clave privada Try {rsaencrypt.loadPrivateKey (rsaencrypt.default_private_key); System.out.println ("Cargando la clave privada con éxito"); } catch (excepción e) {system.err.println (e.getMessage ()); System.err.println ("Falló la clave privada de carga"); } // Test String String CiCryptStr = "Test String chaijunkun"; Pruebe {// cifrado byte [] cipher = rsaencrypt.Encrypt (rsaencrypt.getPublicKey (), ciRyptStr.getBytes ()); // Decrypt byte [] asignxt = rsaencrypt.Decrypt (rsaencrypt.getPrivateKey (), cifrado); System.out.println ("Longitud de texto cifrado:"+ cipher.length); System.out.println (rsaencrypt.bytearrayToString (cifrado)); System.out.println ("Longitud de texto sin formato:"+ EntrextExt.length); System.out.println (rsaencrypt.bytearrayToString (texto sin formato)); System.out.println (nueva cadena (texto de texto)); } catch (excepción e) {system.err.println (e.getMessage ()); }}} En el código, proporciono dos formas de cargar claves públicas y privadas.
Lea por flujo: adecuado para el método de obtener InputStream mediante la indexación de ID recursos en aplicaciones de Android;
Lea por cadena: como se muestra en el código, almacene el contenido de la tecla por línea en constantes estáticas e importe la clave por tipo de cadena.
Ejecute el código anterior y se mostrará la siguiente información:
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 AF AD AB CB 61 03 3C A1 81 56 A5 de C4 79 AA 3E 48 88 09 09 87 AF AB AB CB 61 03 3C A1 81 56 A5 de C4 79 AA 3E 488 EE 30 3D 9f fd 22 87 9e de B1 F4 E8 B2 Longitud de texto plano: 22 54 65 73 74 20 53 74 72 69 6e 67 20 63 68 61 69 6a 75 6E 6B 75 6e Cadena de prueba Chaijunkun
En la función principal comenté "rsaencrypt.GenKeypair ()", que se utiliza para generar aleatoriamente pares de claves (solo generar, usar, no almacenar). Cuando no se usa la clave de archivo, puede comentar el código que carga la clave, habilitar este método o ejecutar el código.
La diferencia entre cargar una clave pública y cargar una clave privada es que cuando se carga la clave pública, X509CodedKeySpec (instrucción clave codificada por X509), y cuando se carga la clave privada, PKCS8EncodedKeySpec (instrucción clave codificada PKCS#8).
Agregado el 22 de febrero de 2012: durante el desarrollo del software Android, se descubrió que el código anterior no funcionaba correctamente. La razón principal es que la clase Sun.Misc.Base64Decoder no existe en el paquete de desarrollo de Android. Por lo tanto, debe buscar el código fuente de RT.jar en Internet. En cuanto al código fuente en el src.zip de JDK, este es solo parte del código fuente en JDK, y los códigos de las clases anteriores no existen. Después de buscar y agregar, el código anterior funciona bien en las aplicaciones de Android. Esto contiene el código correspondiente para esta clase. Además, esta clase también depende de las clases de CeFormateException, CestreameExhausted, CaracterDecoder y Caracterencoder y definiciones de excepción.
Agregado el 23 de febrero de 2012: al principio, escribí este artículo para implementar el cifrado y el descifrado RSA sin confiar en ningún paquete de terceros, pero encontré problemas más tarde. Dado que se debe crear un objeto de cifrado tanto en el método de cifrado como en el método Decrypt Decrypt, este objeto solo puede obtener instancias a través de GetInstance. Hay dos tipos de TI: el primero es especificar solo el algoritmo y no el proveedor; El segundo es especificar ambos. Al principio, el código aún puede ejecutarse, pero encontrará que el resultado de cada cifrado es diferente. Más tarde, se descubrió que la clave pública y privada utilizada por el objeto cifrado se generó aleatoriamente internamente, no la clave pública y privada especificada en el código. Curiosamente, este código que no especifica a un proveedor puede ejecutarse a través de aplicaciones de Android, y el resultado de cada cifrado es el mismo. Creo que, además de algunas funciones de desarrollo del sistema en el SDK de Android, también implementa las funciones del JDK. Puede haber proporcionado a los proveedores correspondientes en su propio JDK, lo que hace que el resultado de cifrado sea el mismo cada vez. Cuando agregué el proveedor de Bouncycastle como el código de muestra en Internet, los resultados de cada cifrado son los mismos.
Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!