RSA解密根据私钥报告错误

发布于 2025-01-23 16:52:46 字数 3051 浏览 2 评论 0原文

我的代码在前端使用RSA:

const rsa = new JSEncrypt();
rsa.setPublicKey(k);
const resultText = rsa.encrypt("violet");
console.log(resultText);

我的代码使用RSA在后端中使用:

byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes("UTF-8"));
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new 
PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,priKey);
String outStr=new String(cipher.doFinal(inputByte));
return outStr;

publickey这样:

    -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA13gYdCmOjR9yqQD7ldzG
ZXabSon6SiLceCK6vRXf4NMbF+EQke0vRpqU3IZ/S1pFdvoQswQabsA4zf0WACVT
iaGIhWDlPu3mecri8rYtmOSfd8GCE0vEgFNvSD6IXRLPeLCB+i7WENBa4fCEtW8W
Hzdas96CLiESbjSAruRasQXP2OLqEA2GU83/069vh8uRKzui+yw0aAXZFyFyFRFa
lxYltFadVpz3+kBplvpzuj82t4fc3yCRbrpeRyTyX1sz0ULSxx/k3/p1OuJtIq9Y
9uN0G4gxhcDFJ4L41uXOln5CPapk7tlsYobhhvxYHw1rrweY+06hrQ7r0Hblv2nH
GQIDAQAB
-----END PUBLIC KEY-----

privateKey这样:

    -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA13gYdCmOjR9yqQD7ldzGZXabSon6SiLceCK6vRXf4NMbF+EQ
ke0vRpqU3IZ/S1pFdvoQswQabsA4zf0WACVTiaGIhWDlPu3mecri8rYtmOSfd8GC
E0vEgFNvSD6IXRLPeLCB+i7WENBa4fCEtW8WHzdas96CLiESbjSAruRasQXP2OLq
EA2GU83/069vh8uRKzui+yw0aAXZFyFyFRFalxYltFadVpz3+kBplvpzuj82t4fc
3yCRbrpeRyTyX1sz0ULSxx/k3/p1OuJtIq9Y9uN0G4gxhcDFJ4L41uXOln5CPapk
7tlsYobhhvxYHw1rrweY+06hrQ7r0Hblv2nHGQIDAQABAoIBAAyqFmXde294BblB
QYhRbafRDNeYvIlW+zZkdC1g98OzJMiGhf7NvhWcSFud3CWFrMeNcyXSe+s+iRgy
Y/SmPP6969RLGa5VNVK7RhOV+aAe7/COAyM3NNmGDehlJIaz8FXbqggWcKaUWIMn
K+WuHdK/4ijoTyZ+8yJfG6Er8tisryLQ9io9+op9g/ZWzaUKgu934/cDxUt70bfm
x+ZEPi6YfkJ1uOpXnnadDyw2RUDcvCM3fK3KF5fqM7SJAXY9b1pmLr+Ccn1qkT9G
I+QHidEsGfJciX5AoHnlIMLPMVIPKBbq4GwC/Ngb41LprNJWlPR38N2ySjky/Jyt
159XWHECgYEA9lx2KfFmyLyVjnkIF3JI50mSZAw4YPBBqB27UInacvxXbjfVURht
xK60GB9OkDbFdeNh89x86Gfwvm5bTq4W8YSH4Obd5Fg8XjTuaicTi03CSfF5SdJn
JLLOUmlqP75gkbEPNUoOfqhqq6IbyJVB3egyL90cd2/wCdJOVLEUly8CgYEA3+Y4
lNdl0xedkDNkWsCyyA4iPSUzVxsuch9hW/VGBwzga8rtiNllpKifVvctQOEu/KUe
vVQRF78ojZaMGT33l6TivnUL54z9Lo9uWghoG8TqMfnG34pFPe3R+zvGP87Hrozw
1EUhiMT198SlB/YHrgGGGlJbG+rlm5GIx3lEdDcCgYA4RSw0LlA0v2ZFkX14pYDj
WxmVwnjKI3ZLqObU4XfE1cA+i4AssrC3wNOfwt7V77ywTYxc/9qD1uHVDS3LzdWt
uoCyrOi3tDOtrNdb5asAIXWkIAR9CRLH/hNEHZHIF3rFLDT2DgE7iso6g59m9DiE
L/nulsleunGQPLnpfDzgvwKBgDRV5Q3tl3CTSZJGYQPRnTikDR7LzkdjJCUq7qAH
IhpNyTuJEKL3ZgnqHGzAlERhHpGRqzDIMMKjPUBzW0YfNPuuYA3y4Bh83UV/42SK
KIOtMK0D3JeuA2dparbWDw4lMIm9iiGkEyWcHH6Q6Z6FxN/InWcTrxZEfu0xRI6T
6wtbAoGAfl5dW9LNoaNfQbgIq+PJKZm9f1frza55mFTJgo3ravdb3GmzWVHN8xRf
nLKyKyNLqbkT35IGc39NkALJLxT5RibkAZLiUiwqdMF63sgODbA9AGTmhe+JHS+V
hBmFnCyp6UiN9E4ZAWcZQILa0rRMftMFngAJ3El0ZP+HziRnNzs=
-----END RSA PRIVATE KEY-----

bu-t,当我进行Java代码解密时,它报告了这样的错误:

java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=111, too big.

我该如何解决此问题?

My code using RSA on the front end:

const rsa = new JSEncrypt();
rsa.setPublicKey(k);
const resultText = rsa.encrypt("violet");
console.log(resultText);

My code using RSA in the backend:

byte[] inputByte = org.apache.commons.codec.binary.Base64.decodeBase64(str.getBytes("UTF-8"));
byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new 
PKCS8EncodedKeySpec(decoded));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,priKey);
String outStr=new String(cipher.doFinal(inputByte));
return outStr;

PublicKey like this:

    -----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA13gYdCmOjR9yqQD7ldzG
ZXabSon6SiLceCK6vRXf4NMbF+EQke0vRpqU3IZ/S1pFdvoQswQabsA4zf0WACVT
iaGIhWDlPu3mecri8rYtmOSfd8GCE0vEgFNvSD6IXRLPeLCB+i7WENBa4fCEtW8W
Hzdas96CLiESbjSAruRasQXP2OLqEA2GU83/069vh8uRKzui+yw0aAXZFyFyFRFa
lxYltFadVpz3+kBplvpzuj82t4fc3yCRbrpeRyTyX1sz0ULSxx/k3/p1OuJtIq9Y
9uN0G4gxhcDFJ4L41uXOln5CPapk7tlsYobhhvxYHw1rrweY+06hrQ7r0Hblv2nH
GQIDAQAB
-----END PUBLIC KEY-----

PrivateKey like this:

    -----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA13gYdCmOjR9yqQD7ldzGZXabSon6SiLceCK6vRXf4NMbF+EQ
ke0vRpqU3IZ/S1pFdvoQswQabsA4zf0WACVTiaGIhWDlPu3mecri8rYtmOSfd8GC
E0vEgFNvSD6IXRLPeLCB+i7WENBa4fCEtW8WHzdas96CLiESbjSAruRasQXP2OLq
EA2GU83/069vh8uRKzui+yw0aAXZFyFyFRFalxYltFadVpz3+kBplvpzuj82t4fc
3yCRbrpeRyTyX1sz0ULSxx/k3/p1OuJtIq9Y9uN0G4gxhcDFJ4L41uXOln5CPapk
7tlsYobhhvxYHw1rrweY+06hrQ7r0Hblv2nHGQIDAQABAoIBAAyqFmXde294BblB
QYhRbafRDNeYvIlW+zZkdC1g98OzJMiGhf7NvhWcSFud3CWFrMeNcyXSe+s+iRgy
Y/SmPP6969RLGa5VNVK7RhOV+aAe7/COAyM3NNmGDehlJIaz8FXbqggWcKaUWIMn
K+WuHdK/4ijoTyZ+8yJfG6Er8tisryLQ9io9+op9g/ZWzaUKgu934/cDxUt70bfm
x+ZEPi6YfkJ1uOpXnnadDyw2RUDcvCM3fK3KF5fqM7SJAXY9b1pmLr+Ccn1qkT9G
I+QHidEsGfJciX5AoHnlIMLPMVIPKBbq4GwC/Ngb41LprNJWlPR38N2ySjky/Jyt
159XWHECgYEA9lx2KfFmyLyVjnkIF3JI50mSZAw4YPBBqB27UInacvxXbjfVURht
xK60GB9OkDbFdeNh89x86Gfwvm5bTq4W8YSH4Obd5Fg8XjTuaicTi03CSfF5SdJn
JLLOUmlqP75gkbEPNUoOfqhqq6IbyJVB3egyL90cd2/wCdJOVLEUly8CgYEA3+Y4
lNdl0xedkDNkWsCyyA4iPSUzVxsuch9hW/VGBwzga8rtiNllpKifVvctQOEu/KUe
vVQRF78ojZaMGT33l6TivnUL54z9Lo9uWghoG8TqMfnG34pFPe3R+zvGP87Hrozw
1EUhiMT198SlB/YHrgGGGlJbG+rlm5GIx3lEdDcCgYA4RSw0LlA0v2ZFkX14pYDj
WxmVwnjKI3ZLqObU4XfE1cA+i4AssrC3wNOfwt7V77ywTYxc/9qD1uHVDS3LzdWt
uoCyrOi3tDOtrNdb5asAIXWkIAR9CRLH/hNEHZHIF3rFLDT2DgE7iso6g59m9DiE
L/nulsleunGQPLnpfDzgvwKBgDRV5Q3tl3CTSZJGYQPRnTikDR7LzkdjJCUq7qAH
IhpNyTuJEKL3ZgnqHGzAlERhHpGRqzDIMMKjPUBzW0YfNPuuYA3y4Bh83UV/42SK
KIOtMK0D3JeuA2dparbWDw4lMIm9iiGkEyWcHH6Q6Z6FxN/InWcTrxZEfu0xRI6T
6wtbAoGAfl5dW9LNoaNfQbgIq+PJKZm9f1frza55mFTJgo3ravdb3GmzWVHN8xRf
nLKyKyNLqbkT35IGc39NkALJLxT5RibkAZLiUiwqdMF63sgODbA9AGTmhe+JHS+V
hBmFnCyp6UiN9E4ZAWcZQILa0rRMftMFngAJ3El0ZP+HziRnNzs=
-----END RSA PRIVATE KEY-----

Bu-t, when i do the java code decryption, it reported such an error:

java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=111, too big.

How can i solve this problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的背包 2025-01-30 16:52:46

1。您正在解码错误。 pem格式具有仪表板线,识别数据类型,一个编码数据的基本64和仪表板线。开始线和终点是格式的一部分,但它们不包含基本64编码的数据;只有之间的界线包含基本64编码的数据。显然,您正在将整个内容(包括开始和终点线)传递给Commons.codec.base64,这导致在实际数据之前和之后解码了一堆垃圾。该垃圾不是有效的。

2。另外,您的数据不是PKCS8清晰的私有键。 PEM类型的“ RSA私钥”是一种openssl定义的格式,其中包含一种“传统”或“传统”格式,即私钥的PKCS1表示。这不是PKCS8,这是Java本地支持的唯一关键格式。这就是为什么SPEC类被命名为pkcs8encodedkeyspec的原因,因为它是编码为PKCS8的密钥规格,更具体地说是PKCS8-CLEAL。如果您通过在base64编码之前删除开始和终点来解决上述问题,Java可以将结果解析为DER,但不能将其作为PKCS8-CLEAR键;您会得到有关“ algid解析错误,而不是序列”的不同例外。为了解决此问题,有5种方法:

  • 更改您最初生成Keypair的任何过程,因此它会生成PKCS8,而不是OpenSSL-Legacy PKCS1。尤其是因为无论如何您都需要替换您通过发布它而折衷的按键,正如207421所说。您不知道该过程是什么,所以我不能提供任何细节。

  • 将您生成的私钥或副本转换为pkcs8-clear。这不是编程或开发和外部的,但是如果您有或获得OpenSSL(在同一或任何可访问且安全的系统上),则可以执行

      openssl pkey -in oldfile -out newfile#1.0.0仅加油,但现在很少见
    # 或者
    openssl pkcs8 -topk8 -nocrypt -in Oldfile -out newfile#甚至是古代版本
     

在拥有PKCS8清除文件后进行,只需删除begin和base base64--解码剩下的内容,然后将其传递给key -factory作为pkcs8encodedkeyspec,就像您已经一样。

  • 使用 https://www.bouncycastle.org 。 “ BCPKIX” JAR具有(Java)代码,可以读取大量OpenSSL支持的PEM格式,包括您拥有的RSA-PKCS1私钥格式。现有的QS很多。只需搜索pemparser和jcapemkeyconverter。

  • 自己转换。解码您拥有的文件正文,在删除了开始和终点后,获取PKCS1密钥,然后为该密钥构建PKCS8格式,然后将其传递给key -factory as pkcs8encodedkeyspec。请参阅NOA RESARE和JEAN-ALEXIS AUFAUVRE的答案,Getting RSA private key from PEM BASE64 Encoded private key file or mine in

  • 完全自己做。解码您没有开始/结束的文件以获取PCKS1,解析为以下eg rfc8447,并构建rsaprivatecrtkeyspec。在上面链接的Qi上,其他一些也可以这样做。但是,这要么需要:使用无证件的内部太阳。使用对ASN.1的支持(和良好支持)的Bouncycastle,但随后将BCPKIX用于上述整个工作更容易;或编写自己的ASN.1解析,这是一项艰巨的工作。

PS:使用RSA加密文本通常是不良设计;它不适合。但这并不是真正的编程问题,也不属于这里。

1. You are decoding wrong. PEM format has a dash-BEGIN line identifying the type of data, a block of base64 encoding the data, and a dash-END line. The BEGIN and END lines are part of the format, but they do not contain base64-encoded data; only the lines in between contain the base64-encoded data. You are apparently passing the whole thing, including the BEGIN and END lines, to commons.codec.Base64, which results in decoding a bunch of garbage before and after the actual data. That garbage isn't valid ASN.1 DER, so when Java tries to parse it as DER it fails.

2. Plus your data is not a PKCS8-clear privatekey. The PEM type 'RSA PRIVATE KEY' is an OpenSSL-defined format that contains a 'traditional' or 'legacy' format, namely the PKCS1 representation of the private key. This is not PKCS8, which is the only key format Java supports natively; that's why the spec class is named PKCS8EncodedKeySpec, because it is a key spec encoded as PKCS8 and more specifically PKCS8-clear. If you fix the above problem by removing the BEGIN and END lines before base64-decoding, Java can parse the result as DER, but not as a PKCS8-clear key; you get a different exception about 'algid parse error, not a sequence'. To fix this there are 5 approaches:

  • change whatever process you use to initially generate the keypair so it generates PKCS8, not OpenSSL-legacy PKCS1. Especially since you need anyway to replace the keypair you compromised by publishing it, as 207421 said. You give no clue what that process is or was, so I can't give any details.

  • convert your generated privatekey, or a copy, to PKCS8-clear. This is not programming or development and offtopic, but if you have or get OpenSSL (on the same or any accessible and secure system), you can do

    openssl pkey -in oldfile -out newfile   # 1.0.0 up only, but older is now rare
    # or
    openssl pkcs8 -topk8 -nocrypt -in oldfile -out newfile   # even ancient versions
    

Once you have a PKCS8-clear file, just remove the BEGIN and END lines and base64-decode what is left, and pass that to KeyFactory as PKCS8EncodedKeySpec as you already do.

  • use https://www.bouncycastle.org . The 'bcpkix' jar has (Java) code to read a large range of OpenSSL-supported PEM formats, including the RSA-PKCS1 private key format you have. There are lots of existing Qs about this; just search for PEMParser and JcaPEMKeyConverter.

  • convert it yourself. Decode the body of the file you have, after removing the BEGIN and END lines, to get the PKCS1 key, then build the PKCS8 format for that key, and then pass it to KeyFactory as PKCS8EncodedKeySpec. See answers by Noa Resare and Jean-Alexis Aufauvre on Getting RSA private key from PEM BASE64 Encoded private key file or mine in Java: Convert DKIM private key from RSA to DER for JavaMail .

  • do it entirely yourself. Decode the file you have without BEGIN/END to get PCKS1, parse that as DER following e.g. RFC8447, and build RSAPrivateCrtKeySpec. Some other As on the Q I linked just above do this. However, this requires either: using undocumented internal sun.* classes, which used to work in Java (hence the existing answers) but which 'modular' Java versions (9 up) since 2017 have steadily made more difficult or impossible; using BouncyCastle which has documented (and good) support for ASN.1 -- but then it's easier to use bcpkix for the whole job as above; or writing your own ASN.1 parsing, which is a good deal of work.

PS: encrypting text with RSA is usually a bad design; it's not suited for that. But that's not really a programming issue and doesn't belong here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文