Escribo una pequeña aplicación para transferir archivos, más o menos como una forma de obtener más información sobre los fundamentos del cifrado programático. La idea es generar un par de claves RSA, intercambiar claves públicas y enviar el AES iv y la clave para un descifrado adicional. Quiero cifrar la clave AES con la clave pública receptores RSA, así:Encriptación de la clave AES con la clave pública RSA
// encode the SecretKeySpec
private byte[] EncryptSecretKey()
{
Cipher cipher = null;
byte[] key = null;
try
{
cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
// contact.getPublicKey returns a public key of type Key
cipher.init(Cipher.ENCRYPT_MODE, contact.getPublicKey());
// skey is the SecretKey used to encrypt the AES data
key = cipher.doFinal(skey.getEncoded());
}
catch(Exception e)
{
System.out.println ("exception encoding key: " + e.getMessage());
e.printStackTrace();
}
return key;
}
que luego escribir el valor clave para el receptor, y descifrarlo, así:
private SecretKey decryptAESKey(byte[] data)
{
SecretKey key = null;
PrivateKey privKey = null;
Cipher cipher = null;
System.out.println ("Data as hex: " + utility.asHex(data));
System.out.println ("data length: " + data.length);
try
{
// assume this loads our private key
privKey = (PrivateKey)utility.loadLocalKey("private.key", false);
cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
cipher.init(Cipher.DECRYPT_MODE, privKey);
key = new SecretKeySpec(cipher.doFinal(data), "AES");
System.out.println ("Key decrypted, length is " + key.getEncoded().length);
System.out.println ("data: " + utility.asHex(key.getEncoded()));
}
catch(Exception e)
{
System.out.println ("exception decrypting the aes key: " + e.getMessage());
e.printStackTrace();
return null;
}
return key;
}
En la consola , en el otro lado, consigo este como salida:
read_bytes for key: 16
data length: 16
Data as hex: <hex string>
Key decrypted, length is 256
java.security.InvalidKeyException: Invalid AES key length: 256 bytes
Además, si se crea una matriz de bytes de tamaño 16 y poner la salida cipher.doFinal (datos) en ella, la matriz es aparentemente cambiar el tamaño a 256 bytes (.leng eso lo dice, al menos). ¿Por qué sería esto, y además, qué estoy haciendo incorrectamente?
edición
He resuelto esto, y pensé que había puesto el tema en caso de que alguien se encuentra con esto. El problema, resultó ser el RSA/ECB/NOPADDING. Por alguna extraña razón, estaba arruinando mi creación de SecretKey cuando lo transferí al cliente. Es podría tener algo que ver con la forma en que estoy generando pares de claves (estoy usando getInstance ("RSA") para eso), pero no estoy del todo seguro.
sombrero Hola, por favor, puesto que su completa ** ** respuesta como una respuesta en lugar de editarlo en su pregunta (que nos dice lo que el el problema era, no la respuesta). Entonces puedes aceptar tu propia respuesta después de un tiempo. O acepte el mío, lo que explica por qué debería usar '" RSA/ECB/PKCS1Padding "' en lugar de '" RSA/ECB/NoPadding "' ... –
Tenga en cuenta que debe usar protección de integridad (por ejemplo, una firma) cuando crea un protocolo en línea que realiza el cifrado. Incluso el cifrado de RSA puede ser aceptable, p. ataques de oráculo de relleno. No tener una protección de integridad es un error común, aunque este problema es limitado si usa PKCS # 1 v1.5 (implícito en '" RSA/ECB/PKCS1Padding "'). –
Como nota al margen, el BCE rara vez es un buen modo para un blockcipher. – CodesInChaos