Java中RSA私钥的加密
我正在尝试使用RSA私钥加密某些内容 我遵循这个例子:Java中RSA私钥的加密,java,encryption,cryptography,rsa,private-key,Java,Encryption,Cryptography,Rsa,Private Key,我正在尝试使用RSA私钥加密某些内容 我遵循这个例子: 但将其转换为使用私钥而不是公钥。按照这个例子,我认为我需要做的是: 以DER格式私钥读取 生成PCKS8EncodedKeySpec 从KeyFactory调用generatePrivate()以获取私钥对象 将该私钥对象与Cipher对象一起使用以进行加密 因此,步骤如下: 密钥是通过以下方式从openssl生成的: openssl genrsa-aes256-out private.pem 2048 然后使用以下命令转换为DER格
但将其转换为使用私钥而不是公钥。按照这个例子,我认为我需要做的是: 以DER格式私钥读取
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是要使用的正确密钥规范吗
- 关于无效密钥规范错误有什么想法吗
密码
用私钥加密,而不是用签名
签名。我不确定所有RSACipher
提供程序是否会使用正确的块类型进行设置,但值得一试
尽管如此,我认为您正在尝试加载一个非标准的OpenSSL格式密钥。使用rsa将其转换为DER本质上只是一个base-64解码;密钥的结构不是PKCS#8
相反,在genrsa
之后,使用openssl pkcs8
命令将生成的密钥转换为未加密的PKCS#8,DER格式:
openssl pkcs8 -topk8 -nocrypt -in private.pem -outform der -out private.der
这将生成一个未加密的私钥,该私钥可以使用无法使用私钥加密的PKCS8EncodedKeySpec加载。如果JCE允许你这么做,那只是偶然的 你需要使用签名。下面是实现这一点的代码片段
signer = Signature.getInstance("SHA1withRSA");
signer.initSign(privateKey); // PKCS#8 is preferred
signer.update(dataToSign);
byte[] signature = signer.sign();
允许使用私钥进行加密并非偶然。如果要将签名分解为单独的散列和加密,则必须使用私钥进行加密。 假设我有一个需要签名的文档,并且我的密钥驻留在网络HSM上。现在,要么我将整个文档流式传输到HSM进行签名,要么我可以创建一个本地哈希并将其流式传输到HSM进行单独加密。
我的选择将取决于本地哈希计算是否为我提供了更好的性能,即具有网络延迟的viz委托哈希计算。这个问题很老了,但我最近偶然发现了这个问题(我正在实现一些协议的要求,这些协议要求使用私钥进行加密)。我将引用以下文章: 我最近偶然发现了同样的问题,在咨询“开发”(不管是谁)裁定私钥不能用于加密后,提交了PMR 22265、49R和IBM支持。无论我多么努力地与他们争论私钥不应用于数据保护,这只是加密背后的一个目的,使用私钥进行加密以实现不可否认性是完全正确的,他们的信念是不可动摇的。你必须爱那些坚持2x2=5的人 我是如何解决这个问题的:本质上,我用私钥的加密材料创建了一个公钥对象。如果要避免“公钥不能用于解密”异常,则需要执行相反的操作,使用公钥的加密材料创建私钥对象,以使用公钥进行解密 试试这个:
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
老实说,我不知道签名。为了确保我理解它的用法,我将初始化signature对象,用我想要签名的字节调用update,然后调用sign?然后我可以把sign返回的字节存储为我的数字签名?您好。有人最终解决了这个问题吗?我有一个私钥,无法加载到java中继续签名阶段。我的私钥是RSA,PKCS#8 DER,它有密码。如何将其加载到java中?我的例子中的异常是
java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:IOException:DER input,Integer tag error
@BRabbit27要直接加载私钥,它必须是未加密的。使用上面显示的opensslpkcs8
命令,添加选项-inform der
;它将提示您输入密码。如果您希望对私钥进行加密(我强烈建议),则需要将其添加到密钥存储(如PKCS#12文件),并通过Java中的KeyStore
API对其进行访问。@erickson我尝试了该命令,但在解密密钥时显示错误(我使用的是WinOpenSSL)。我使用的命令是opensslpkcs8-topk8-nocrypt-in myKey.key-inform der-outform der-out myNoCryptKey.key
更新-nocrypt选项应该做什么?我想我做了一个类似这样的解决方法openssl pkcs8-inform DER-in-myKey.key-outform PEM-out myKeyInPEM.key
它向我询问密码,然后openssl pkcs8-topk8-nocrypt-in-myKeyInPEM-outform DER-out myKeyInDERNoCrypted.key
它没有询问我的密码,但结果文件似乎是相同的myKey.keys/public/private/
在您的第一行中。我浏览了这篇文章并用Java生成了它们:如果您将私钥指数视为公共指数并分发它,这是非常危险的,因为给定私钥(您称之为“公钥”),很容易派生出实际的公钥(您现在称之为“私钥”)。不要不小心将“公钥”公开,否则您的系统将受到危害。这可能很简单,只需猜测“私钥”的指数是65537。我搜索了这么久。我非常感谢这个答案。“私钥和公钥”这个名称在这个用例中是完全错误的
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);