Estoy intentando configurar el cifrado RSA para que pueda hacer una biblioteca simple para mí mismo para utilizar en el futuro y no puedo obtener este código simple de trabajo. Aquí está el código fuente:
package rsa.testing;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import javax.crypto.Cipher;
public class AloneTest
{
public static void doTest()
{
try
{
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048);
KeyPair pair = gen.genKeyPair();
System.out.println("Public key: " + byteArrayToString(pair.getPublic().getEncoded()));
System.out.println("Private key: " + byteArrayToString(pair.getPrivate().getEncoded()));
Cipher encryptPublic = Cipher.getInstance("RSA");
encryptPublic.init(Cipher.ENCRYPT_MODE, pair.getPublic());
Cipher decryptPublic = Cipher.getInstance("RSA");
decryptPublic.init(Cipher.DECRYPT_MODE, pair.getPublic());
Cipher encryptPrivate = Cipher.getInstance("RSA");
encryptPrivate.init(Cipher.ENCRYPT_MODE, pair.getPrivate());
Cipher decryptPrivate = Cipher.getInstance("RSA");
decryptPrivate.init(Cipher.DECRYPT_MODE, pair.getPrivate());
System.out.println("All ciphers created.");
System.out.println();
String plainText = "Hello World!";
System.out.println("Plain text: " + plainText);
String encrypted = new String(encryptPrivate.doFinal(plainText.getBytes()));
System.out.println("Encrypted: " + encrypted);
String decrypted = new String(decryptPublic.doFinal(encrypted.getBytes()));
System.out.println("Decrypted: " + decrypted);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private static String byteArrayToString(byte[] bytes)
{
String str = "";
for (byte b : bytes)
{
str += b + " ";
}
return str.trim();
}
}
Y esto la salida (imagen porque no me deja copiar el texto cifrado).
¿Algunas ideas?
EDIT: Modifica la siguiente:
String plainText = "Hello World!";
System.out.println("Plain text: " + plainText);
String encrypted = byteToBase64String(encryptPublic.doFinal(plainText.getBytes()));
System.out.println("Encrypted: " + encrypted);
String decrypted = byteToBase64String(decryptPublic.doFinal(encrypted.getBytes()));
System.out.println("Decrypted: " + decrypted);
Método utilizado para convertir bytes de base 64:
private static String byteToBase64String(byte[] bytes)
{
return Base64.getEncoder().encodeToString(bytes);
}
Pero ahora me sale este error:
Plain text: Hello World!
Encrypted: dCTsYrQTDfNkRr6+nupWW4ntsmD69wrWS1TDvS3Uk1B6lCKkycegAb7wJgnXNolZ58dRXgbzEyCkeM/IbH0ruIEMfuhS5vrggo1s9+6MQN2hW1I4iElJfAdGKYQ8H9pFhAws+VQGetjwvJwUI9iWIi15721vc508/ks7rn4oQOk=
javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:344)
at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at rsa.testing.AloneTest.doTest(AloneTest.java:40)
at rsa.testing.Main.main(Main.java:21)
¿Hay que hacer algún tipo de división? O estoy haciendo algo más mal?
Se echa en falta la siguiente:
en el cifrado con clave pública se debe utilizar la clave privada para descifrar
y también
en el cifrado con la clave privada se debe usar la clave pública para descifrar
ACTUALIZAR
Al cifrar por ejemplo, con la clave privada a continuación, tratando de descifrar con la misma clave privada que tendrá que java.crypto.BadPaddingException
No puedo compartir el código que demuestra esto, pero yo probado usando:
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(2048);
keyPair = keyPairGen.generateKeyPair();
mientras que para Cipher utilicé:
Cipher.getInstance("RSA/ECB/PKCS1Padding")