Java中使用RSA私钥加密
我正在尝试使用 RSA 私钥加密某些内容。
我正在遵循这个例子: http://www.junkheap.net/content/public_key_encryption_java
但将其转换为使用私钥而不是公钥。按照这个例子,我认为我需要做的是:
- 读入 DER 格式的私钥
- 生成 PCKS8EncodedKeySpec
- 从 KeyFactory 调用generatePrivate() 来获取私钥对象
- 使用该私钥对象与 Cipher 对象进行加密
所以,步骤:
密钥是从 openssl 生成的:
openssl genrsa -aes256 -out private.pem 2048
,然后转换为 DER 格式:
openssl rsa -in private.pem -outform DER -out private.der
我使用以下方法生成 PKCS8EncodedKeySpec
byte[] encodedKey = new byte[(int)inputKeyFile.length()];
try {
new FileInputStream(inputKeyFile).read(encodedKey);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
return privateKeySpec;
然后使用以下方法生成私钥对象:
PrivateKey pk = null;
try {
KeyFactory kf = KeyFactory.getInstance(RSA_METHOD);
pk = kf.generatePrivate(privateKeySpec);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pk;
但是,在调用时:
pk = kf.generatePrivate(privateKeySpec);
我得到:
java.security.spec.InvalidKeySpecException: Unknown key spec.
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275)
at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:237)
问题:
- 一般方法正确吗?
- PCKS8EncodedKeySpec 是正确使用的密钥规范吗?
- 关于无效的关键规范错误有什么想法吗?
I'm trying to encrypt some content with an RSA private key.
I'm following this example:
http://www.junkheap.net/content/public_key_encryption_java
but converting it to use private keys rather than public. Following that example, I think what I need to do is:
- Read in a DER-format private key
- Generate a PCKS8EncodedKeySpec
- call generatePrivate() from KeyFactory to get a private key object
- Use that private key object with the Cipher object to do the encryption
So, the steps:
The key was generated from openssl with:
openssl genrsa -aes256 -out private.pem 2048
and then was converted to DER format with:
openssl rsa -in private.pem -outform DER -out private.der
I generate the PKCS8EncodedKeySpec with:
byte[] encodedKey = new byte[(int)inputKeyFile.length()];
try {
new FileInputStream(inputKeyFile).read(encodedKey);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
return privateKeySpec;
And then generate the private key object with:
PrivateKey pk = null;
try {
KeyFactory kf = KeyFactory.getInstance(RSA_METHOD);
pk = kf.generatePrivate(privateKeySpec);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return pk;
However, on the call to:
pk = kf.generatePrivate(privateKeySpec);
I get:
java.security.spec.InvalidKeySpecException: Unknown key spec.
at com.sun.net.ssl.internal.ssl.JS_KeyFactory.engineGeneratePrivate(DashoA12275)
at com.sun.net.ssl.internal.ssl.JSA_RSAKeyFactory.engineGeneratePrivate(DashoA12275)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:237)
Questions:
- Is the general approach right?
- Is the PCKS8EncodedKeySpec the right keyspec to use?
- Any thoughts on the invalid key spec error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您无法使用私钥加密。如果 JCE 允许您这样做,那只是偶然。
您需要使用签名。这是执行此操作的代码片段,
You can't encrypt with private key. If JCE allows you to do that, it's just by accident.
You need to use signature. Here are the code snippet to do that,
首先,我很困惑为什么您计划使用
Cipher
来使用私钥进行加密,而不是使用Signature
进行签名。我不确定所有 RSACipher
提供程序都会使用正确的块类型进行设置,但值得一试。不过,抛开这一点,我认为您正在尝试加载非标准 OpenSSL 格式的密钥。使用 rsa 将其转换为 DER 本质上只是一个 Base-64 解码;密钥的结构不是 PKCS #8。
相反,在
genrsa
之后,使用openssl pkcs8
命令将生成的密钥转换为未加密的 PKCS #8、DER 格式:这将生成一个未加密的私钥,可以使用一个
PKCS8EncodedKeySpec
。First of all, I'm confused why you are planning to use a
Cipher
to encrypt with a private key, rather than signing with aSignature
. I'm not sure that all RSACipher
providers will use the correct block type for setup, but it's worth a try.Setting that aside, though, I think that you are trying to load a non-standard OpenSSL-format key. Converting it to DER with
rsa
is essentially just a base-64 decode; the structure of the key is not PKCS #8.Instead, after
genrsa
, use theopenssl pkcs8
command to convert the generated key to unencrypted PKCS #8, DER format:This will produce an unencrypted private key that can be loaded with a
PKCS8EncodedKeySpec
.允许使用私钥加密并非偶然。如果您想将签名分解为单独的散列和加密,那么使用私钥加密是必不可少的。
假设我有一份需要签名的文档,并且我的密钥位于网络 HSM 上。现在,我可以将整个文档流式传输到 HSM 进行签名,也可以创建本地哈希并将其流式传输到 HSM 进行单独加密。
我的选择将取决于本地哈希计算是否为我提供更好的性能,即具有网络延迟的可视化委托哈希计算。
Its not an accident that encryption with private key is allowed. If you want to break a signature into individual hashing and encryption, then encrypting with private key is essential.
Lets say I have a document which i need to sign and my key resides on a network HSM. Now either I stream the entire document to the HSM to sign or I can create a local hash and stream it to the HSM for encryption alone.
My choice will depend on whether the local hash computation gives me better performance viz a viz delegated hash computation with network latency.
这个问题很老了,但我最近偶然发现了这个问题(我正在实现一些需要使用私钥加密的协议的要求)。我将引用 论坛:
This question is pretty old, but I recently stumbled upon the problem (I'm implementing requirements of some protocol which requires encryption with private key). I will just quote the post from forum:
试试这个:
try this: