Я пишу небольшое приложение для передачи файлов более или менее, чтобы узнать больше о программных основах шифрования. Идея состоит в создании пары ключей RSA, обмене открытыми ключами и отправке AES iv и ключа для дальнейшего расшифровки. Я хочу, чтобы зашифровать ключ AES с открытым ключом приемники RSA, например, так:Шифрование ключа AES с открытым ключом 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;
}
Я тогда выписывать значение ключа к приемнику, и расшифровать его так:
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;
}
В консоли , с другой стороны, я получаю это как выход:
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
Кроме того, если создать байтовый массив размером 16 и поместить вывод cipher.doFinal (данные) в него, массив казалось бы уменьшен до 256 байт (.leng th говорит так, по крайней мере). Почему это было бы и дальше, что я делаю неправильно?
редактировать
Я решил это, и думал, что я отправлю вопрос в случае, если кто-то работает в этом. Оказывается, это проблема RSA/ECB/NOPADDING. По какой-то странной причине это заставило меня создать SecretKey, когда я передал его клиенту. Это может иметь какое-то отношение к тому, как я генерирую ключевые пары (я использую getInstance («RSA») для этого), но я не совсем уверен.
Привет шлет, пожалуйста, напишите ваши ** ** полный ответ в ответ вместо редактирования в вашем вопросе (вы сказать нам, что проблема была, а не ответ). Затем вы можете принять свой собственный ответ через некоторое время. Или примите мое, что объясняет, почему вы должны использовать '' RSA/ECB/PKCS1Padding'' вместо '' RSA/ECB/NoPadding'' ... –
Обратите внимание, что вы должны использовать защиту целостности (например, подпись) при создании онлайн-протокол, который выполняет шифрование. Даже шифрование RSA может быть приемлемо, например, атаки оракула. Отсутствие защиты целостности является распространенной ошибкой, хотя эта проблема ограничена, если вы используете PKCS # 1 v1.5 (подразумевается «RSA/ECB/PKCS1Padding»). –
В качестве побочного элемента ECB редко является хорошим режимом для блочного шифрования. – CodesInChaos