HSM错误| 私钥必须是RSAPrivate(Crt)密钥的实例或具有PKCS#8

从HSM检索私钥时解密数据时收到错误。

我在java.security中添加了sunpkcs11提供程序。 因此,不要通过代码添加提供程序。 文本已成功加密。 但是,在解密加密文本时,我在下面的行中得到以下错误:

cipher.init(Cipher.DECRYPT_MODE, privateKey); 

我在这里失踪的是什么?

错误:

  Caused by: java.security.InvalidKeyException: Private key must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding at sun.security.pkcs11.P11RSAKeyFactory.implTranslatePrivateKey(P11RSAKeyFactory.java:101) [sunpkcs11.jar:1.7.0_85] at sun.security.pkcs11.P11KeyFactory.engineTranslateKey(P11KeyFactory.java:132) [sunpkcs11.jar:1.7.0_85] at sun.security.pkcs11.P11KeyFactory.convertKey(P11KeyFactory.java:65) [sunpkcs11.jar:1.7.0_85] at sun.security.pkcs11.P11RSACipher.implInit(P11RSACipher.java:199) [sunpkcs11.jar:1.7.0_85] at sun.security.pkcs11.P11RSACipher.engineInit(P11RSACipher.java:168) [sunpkcs11.jar:1.7.0_85] at javax.crypto.Cipher.init(Cipher.java:1068) [jce.jar:1.7.0_85] at javax.crypto.Cipher.init(Cipher.java:1012) [jce.jar:1.7.0_85]enter code here 

以下是代码:

 import java.io.ByteArrayOutputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.Certificate; import javax.crypto.Cipher; import javax.xml.bind.DatatypeConverter; import sun.security.pkcs11.SunPKCS11; public class App { public static void main(String[] args) throws Exception { try { String passphrase = "mysecretkey"; SunPKCS11 provider = new SunPKCS11("/home/user/pkcs11.cfg"); KeyStore keystore = KeyStore.getInstance("PKCS11", provider); keystore.load(null, passphrase.toCharArray()); String textToEncrypt = "this is my text"; Certificate cert = keystore.getCertificate("my-SHA1WITHRSA-2048-bits-key"); PublicKey publicKey = cert.getPublicKey(); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider); cipher.init(Cipher.ENCRYPT_MODE, publicKey); String encryptedData = DatatypeConverter.printBase64Binary(cipher.doFinal(textToEncrypt.getBytes())); PrivateKey privateKey = (PrivateKey) keystore.getKey("my-SHA1WITHRSA-2048-bits-key", passphrase.toCharArray()); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decodedEncryptedData = DatatypeConverter.parseBase64Binary(encryptedData); ByteArrayOutputStream stream = new ByteArrayOutputStream(); int blocks = decodedEncryptedData.length / 256; int offset = 0; for (int blockIndex = 0; blockIndex < blocks; blockIndex++) { byte[] nextBlock = getNextBlock(decodedEncryptedData, offset); stream.write(cipher.doFinal(nextBlock)); offset += 256; } } catch (Exception e) { e.printStackTrace(); } } private static byte[] getNextBlock(byte[] cipherText, int offset) { byte[] block = new byte[256]; System.arraycopy(cipherText, offset, block, 0, 256); return block; } } 

我是如何解决的:

导致此问题的根本原因是sunpkcs11提供程序已静态和动态加载。

即在java.security中,已经添加了提供者条目以及cfg路径。

此外,在代码中,使用cfg文件再次初始化提供程序。

这导致了这个问题。

更改后:

 SunPKCS11 provider = new SunPKCS11("/home/user/pkcs11.cfg"); 

至:

 SunPKCS11 sunPKCS11Provider = (SunPKCS11) Security.getProvider("SunPKCS11"); 

问题得到解决。

我使用了以下代码,问题已经解决

  SunPKCS11 provider = new SunPKCS11("/home/user/pkcs11.cfg"); Security.addProvider(provider); KeyStore keystore = KeyStore.getInstance("PKCS11"); keystore.load(null, passphrase.toCharArray());