gpt4 book ai didi

java - 使用 RSA 公钥加密 AES key

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:03:26 25 4
gpt4 key购买 nike

我正在编写一个用于传输文件的小型应用程序,或多或少是作为了解更多编程加密基础知识的一种方式。这个想法是生成一个 RSA key 对,交换公钥,然后发送 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;
}

然后我将 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 转移给客户时,它搞砸了我创建的 SecretKey。它可能与我生成 key 对的方式有关(为此我使用 getInstance("RSA")),但我不完全确定。

最佳答案

正如 owlstead 所提到的,您不能仅使用“原始”RSA 而无需填充进行加密/解密。一方面它非常不安全,另一方面,Java 库甚至不支持它。以下是使用 RSA key 对加密/解密 AES key 的工作代码。

private byte[] EncryptSecretKey ()
{
Cipher cipher = null;
byte[] key = null;

try
{
// initialize the cipher with the user's public key
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, contact.getPublicKey() );
key = cipher.doFinal(skey.getEncoded());
}
catch(Exception e )
{
System.out.println ( "exception encoding key: " + e.getMessage() );
e.printStackTrace();
}
return key;
}

AES key 的解密如下所示:

private SecretKey decryptAESKey(byte[] data )
{
SecretKey key = null;
PrivateKey privKey = null;
Cipher cipher = null;

try
{
// this is OUR private key
privKey = (PrivateKey)utility.loadLocalKey(
ConfigFrame.privateKeyLocation, false);

// initialize the cipher...
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privKey );

// generate the aes key!
key = new SecretKeySpec ( cipher.doFinal(data), "AES" );
}
catch(Exception e)
{
System.out.println ( "exception decrypting the aes key: "
+ e.getMessage() );
return null;
}

return key;
}

关于java - 使用 RSA 公钥加密 AES key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9658921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com