我正在编写一个小型的文件传输应用程序,主要是为了更深入地学习编程加密基础知识。我的想法是生成RSA密钥对,交换公钥,并发送AES iv和key以进行进一步解密。我希望使用接收者的RSA公钥来加密AES key,方法如下:
// 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(data)的输出放入其中,则该数组似乎被调整为256个字节(至少.length这样说)。这是为什么呢?并且更进一步,我做错了什么吗?
编辑 我已经解决了这个问题,并认为我应该发布此问题以防有人遇到。问题实际上是RSA / ECB / NOPADDING。由于某种奇怪的原因,当我将SecretKey传输到客户端时,它会破坏我的创建。这可能与我如何生成密钥对有关(我正在使用getInstance(“RSA”)),但我不确定。
"RSA/ECB/PKCS1Padding"
而不是"RSA/ECB/NoPadding"
... - Maarten Bodewes