java使用RSA公钥加密AES密钥
我正在编写一个用于传输文件的小应用程序,或多或少是为了了解更多编程加密基础。其想法是生成一个RSA密钥对,交换公钥,并将AES iv和密钥发送给用户进行进一步解密。我想用RSA公钥加密AES密钥,如下所示:
// 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的字节数组,并放入密码。如果将最终(数据)输出到其中,数组的大小似乎调整为256字节(至少长度是这样)。为什么会这样,更进一步,我做错了什么
编辑
我解决了这个问题,我想我会发布这个问题,以防有人遇到这个问题。事实证明,问题在于RSA/ECB/NOP。出于某种奇怪的原因,当我把秘钥转交给客户时,它把我的秘钥制作搞砸了。这可能与我如何生成密钥对有关(我使用getInstance(“RSA”)来实现),但我不完全确定
# 1 楼答案
不能只使用“原始”RSA加密数据而不进行任何填充。你需要某种填充方案,哪怕只是出于安全考虑。通常使用“RSA/ECB/PKCS1添加”。这可以加密比密钥大小小11字节的数据。它确保数据符合模数,并添加至少8字节的随机数据,以确保两次加密(例如“是”一词)不会产生两个相同的密码文本。最后,它确保您可以找到加密数据的大小(以八位字节为单位),因此您可以简单地加密构成AES密钥的16、24或32字节
# 2 楼答案
Comment Source
要获得正确的密钥大小,可以对密钥(SHA)使用哈希算法,这将为您提供固定的输出大小。否则,您可以只使用前16个字节作为键,而忽略其余的?祝你好运
# 3 楼答案
正如owlstead提到的,您不能只使用“原始”RSA,而不使用填充进行加密/解密。一方面它非常不安全,另一方面,Java库甚至不支持它。下面是使用RSA密钥对加密/解密AES密钥的工作代码
AES密钥的解密如下所示: