2011-05-20 34 views
10

Estoy tratando de codificar una simple "prueba" de cadenas de un lado a otro.Java RSA Encryption

public static String encode(Key publicKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

    byte[] byteData = data.getBytes(); // convert string to byte array 

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object 
    cipher.init(Cipher.ENCRYPT_MODE, publicKey); // initialize object's mode and key 

    byte[] encryptedByteData = cipher.doFinal(byteData); // use object for encryption 

    return new String(encryptedByteData); // convert encrypted byte array to string and return it 

} 

public static String decode(Key privateKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 

    byte[] byteData = data.getBytes(); // convert string to byte array 

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object 
    cipher.init(Cipher.DECRYPT_MODE, privateKey); // initialize object's mode and key 

    System.out.println(byteData.length); 

    byte[] decryptedByteData = cipher.doFinal(byteData); // use object for decryption 

    return new String(decryptedByteData); // convert decrypted byte array to string and return it 

} 

Sin embargo, aunque el cifrado funciona bien (algoritmo es "RSA"), cuando se trata de descifrar la cadena acabo recibido de cifrado de "prueba", consigo siguiente excepción:

javax.crypto.IllegalBlockSizeException: datos no debe ser superior a 256 bytes

¿Debo dividir los bytes cifrados en trozos de 256 con el fin de ser capaz de descifrarlo?

Respuesta

9

No se pueden convertir de manera confiable bytes aleatorios a String. Los resultados dependerán de cuál sea la codificación de caracteres predeterminada en la máquina donde ejecuta esto. Con muchas codificaciones, el texto cifrado se dañará y la información se perderá.

modificar el código para utilizar un byte[] lugar (el resultado de la doFinal método `'().

Si necesita convertir el byte[] a una cadena de caracteres, utilizar una codificación como base 64.

+0

¡Ah, perfecto, gracias, funciona a la perfección! Sí, creo que la corrupción es cuando convierto la matriz de bytes cifrados en una cadena. – arik

4

De here:

El algoritmo RSA sólo puede cifrar los datos que tiene una longitud máxima de bytes de la longitud de la clave RSA en bits dividido con ocho menos once relleno bytes, es decir, número de bytes máximos = clave longitud en bits/8 - 11. Si desea encriptar datos más grandes, utilice una clave más grande, por ejemplo, , una clave con 4096 bits le permitirá encriptar 501 bytes de datos.

+1

Aunque he leído la oración en la misma redacción que un resultado de búsqueda de Google, no fue correcto configurar la clave más alta para mí. Probé la longitud de la matriz de bytes del cifrado y noté que al aumentar la longitud de la clave de 2048 a 4096 también lo hacía la longitud del conjunto de bytes, en ninguno de los casos cabía, en ambos casos obtuve la excepción. – arik

3

Si tiene datos largos, debe dividirlos en fragmentos de datos que se ajusten y encriptar/desencriptar cada uno de ellos (no es una buena idea) o encriptarlos/descifrarlos usando un algoritmo simétrico (AES/DES/RC4/etc. .), cifre la clave simétrica con la clave pública RSA y envíe ambas al otro lado. (idea mucho mejor).

El segundo enfoque es un enfoque muy común, ya que los algoritmos de encriptación asimétrica son mucho más caros que los algoritmos simétricos (tanto para el cifrado como para el desencriptado).

+0

Gracias. Lo haré cuando los datos realmente excedan el límite, pero no es ahí donde se encuentra el problema al encriptar una cadena tan simple como "prueba". – arik

+0

Sí, leí mal su pregunta, pero creo que es un buen consejo para el futuro de todos modos. ¡Buena suerte! – MByD