java.security.InvalidKeyException:不支持的密钥类型:Sun RSA 公钥,2048 位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28024766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:51:54  来源:igfitidea点击:

java.security.InvalidKeyException: Unsupported key type: Sun RSA public key, 2048 bits

javaencryptiondigital-signature

提问by Monika Tiwari

I want to Sign my data, for that purpose I am using Windows-MYkeystore and SunMSAPIprovider for encrypting and decrypting some text using my certificate. But there is Exception:

我想对我的数据进行签名,为此我使用Windows-MY密钥库和SunMSAPI提供程序来使用我的证书加密和解密一些文本。但有例外:

InvalidKeyException: Unsupported key type: Sun RSA public key, 2048 bits.

on line

在线的

aesCipher1.init(Cipher.DECRYPT_MODE, publicKey);

Actually I want to encrypt my data with private key and decrypt with the public key.

其实我想用私钥加密我的数据并用公钥解密。

My System Configuration is: Windows 7, 64-bit

我的系统配置是:Windows 7, 64-bit

How to deal with this problem?

如何处理这个问题?

My code is this:

我的代码是这样的:

X509Certificate c = (X509Certificate)keyStore.getCertificate(alias);
String serialNumber = c.getSerialNumber().toString();
Key privateKey = (Key) keyStore.getKey(DSCName, null);
Certificate[] chain = keyStore.getCertificateChain(DSCName);
DataOutputStream fout = new DataOutputStream(outstream);
  Provider p = keyStore.getProvider();
  String myData = "data to encrypt";
  PublicKey publicKey =  c.getPublicKey();

String cipherText = null;                   
final Cipher aesCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding",keyStore.getProvider().getName());
aesCipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] byteDataToRate = myData.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteDataToRate);
cipherText = new BASE64Encoder().encode(byteCipherText);
System.out.println("cipherText:" + cipherText);
// ----------------------------
final Cipher aesCipher1 = Cipher.getInstance("RSA/ECB/PKCS1Padding",keyStore.getProvider().getName());
aesCipher1.init(Cipher.DECRYPT_MODE, public Key);

byte[] byteDecryptedText = aesCipher1.doFinal(byteCipherText);
System.out.println(byteDecryptedText);
String decryptedText = new String(byteDecryptedText);

my output is:

我的输出是:

cipherText:f8/rPxpIgJXILNLSeESOCv2KYj4tomVIASAA45NLmBzA/iOWEsLJvCLYI9+pAqTwx7N8spWP+9HN
ZgaShxGPDjnVkqnuFlzbmXCZUCLMEbSULwzKQsSYMNIDq2x7J376g+GRm8kBYMdgGdNJtMIx8sXP
qvyWxNSWPdhe1xFna1w0DuqK1mR30/ZdU9lACyCMSeXK22K2FM+V7oDR9MHgbpB0oeHfH66emkk0
lpKqu6Wr9D43QwYmXAo/u/8gD3dwr7qdOwarTopfbCLqWfWn8DuyYTwDY/vbdiZJfPZfGNMrnhzq
/tdHm2ScNreskQ8HiMfeH0Iih8MPoiIVac+FVA==
java.security.InvalidKeyException: Unsupported key type: Sun RSA public key, 2048 bits
  modulus: 23713039584215334199359298536212699709102701257112982501126249760223003496547622902125282473933441681112130016090107773380054108139644420960634826102273499375704409005561487813169118425678603332231931611435818472883984384798084461353789618974581650786153976157396519738737858475541085942135666317196760918526775906883258164847855820472961868914809656826030205995272605151893433820872358865888343062850551910390809733698336903383894285445543225373616943057201233572494941972199152175995644435643142748595739783632001488705350282425460845827015899242784498630928265270728853274152332569674675710858589941739193789787683
  public exponent: 65537
eXCEPTION::
    at sun.security.mscapi.RSACipher.engineGetKeySize(RSACipher.java:345)
    at javax.crypto.Cipher.b(DashoA13*..)
    at javax.crypto.Cipher.a(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at javax.crypto.Cipher.init(DashoA13*..)
    at EncryptDecrypt.selectActionPerformed(EncryptDecrypt.java:530)
    at EncryptDecrypt.access(EncryptDecrypt.java:414)
    at EncryptDecrypt.actionPerformed(EncryptDecrypt.java:209)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access
// sign
Signature instance = Signature.getInstance("SHA256withRSA");
instance.initSign(privateKey, new SecureRandom());
instance.update(myData.getBytes("UTF-8")); // encoding is important
byte[] signature = instance.sign();

// verify
instance.initVerify(publicKey);
instance.update(myData.getBytes("UTF-8")); // encoding is important
System.out.println(instance.verify(signature));
0(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext.doIntersectionPrivilege(Unknown Source) at java.security.AccessControlContext.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.awt.EventQueue.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)

采纳答案by Artjom B.

Although signature generation is a similar operation to encryption when using RSA, but Java has different classes that are used for generating signatures.

虽然在使用 RSA 时,签名生成是一种类似于加密的操作,但是 Java 有不同的类用于生成签名。

final Cipher aesCipher1 = Cipher.getInstance("RSA/ECB/PKCS1Padding"); //,keyStore.getProvider().getName());
aesCipher1.init(Cipher.DECRYPT_MODE, publicKey);

回答by Omikron

The cause of the exception is that you are using the SunMSCAPIprovider for a public keyoperation, which is unfortunately not possible.

异常的原因是您使用SunMSCAPI提供程序进行公钥操作,不幸的是这是不可能的。

Just remove the provider parameter in this line of code and it will work:

只需删除这行代码中的 provider 参数,它就会起作用:

##代码##

Background info: Your public key is a instance of sun.security.rsa.RSAPublicKeyImpland the Cipher implementation of SunMSCAPI provider only accepts sun.security.mscapi.RSAPrivateKey. This means that you have to do private key operations with the SunMSCAPI provider and public key operations with the SunJCE provider.

背景信息:您的公钥是 的实例,sun.security.rsa.RSAPublicKeyImpl并且 SunMSCAPI 提供程序的密码实现仅接受sun.security.mscapi.RSAPrivateKey。这意味着您必须使用 SunMSCAPI 提供程序进行私钥操作,并使用 SunJCE 提供程序进行公钥操作。