我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个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的字节数组,并将cipher.doFinal(data)输出放入其中,则该数组的大小似乎已调整为256个字节(至少.length这样说)。为什么会这样,而且进一步,我在做错什么?
编辑
我解决了这个问题,并以为我会发布这个问题,以防有人碰到这个问题。事实证明,问题出在RSA / ECB /
NOPADDING。出于某种奇怪的原因,当我将SecretKey转移到客户端时,它正在破坏我的创建。它 可能
与生成密钥对的方式有关(我为此使用了getInstance(“ RSA”)),但我不确定。
如owlstead所述,如果不使用填充进行加密/解密,就不能仅使用“原始”
RSA。一方面,它是非常不安全的;另一方面,Java库甚至不支持它。以下是使用RSA密钥对对AES密钥进行加密/解密的工作代码。
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密钥的解密如下所示:
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;
}
这是我的密码 抱歉,如果我的代码一团糟。
我使用Delphi XE和Lockbox3.5,我想加密一个字符串,该字符串具有支付网关提供的公钥,需要操作,公钥类似于:------开始公钥------这里的职员------结束公钥------我无法使RSA编解码器读取该公钥,我的代码如下: 编解码器cdcRA链接到CryptoLibrary,密码为(RSA公钥加密系统*),链接模式为空,但此代码失败,并出现内存不足错误。谢谢你的提示。。 演示
并且我将这个函数称为用RSA公钥加密DSA密钥的函数:
但这总是给我以下的例外- 我的键盘生成逻辑- 我的加密逻辑- Base64 Util方法-
说明 微信支付-获取RSA加密公钥SDK,企业付款到银行卡接口需要。 你还需要执行openssl rsa -RSAPublicKey_in -in weixin-rsa-public.pem -pubout 将命令行输出的证书内容覆盖到weixin-rsa-public.pem文件中才可使用 官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/mch
我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。