2016-05-13 192 views
2

從HSM檢索私鑰時解密數據時收到錯誤。HSM錯誤|私鑰必須是RSAPrivate(Crt)密鑰的實例或具有PKCS#8

我在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; 
    } 

} 

回答

5

如何解決:

這個問題的

根本原因是sunpkcs11供應商處得到裝載兩個靜態和動態。

即在java.security中的 ,已經添加了提供程序條目以及cfg路徑。

另外,在代碼中,提供者被再次用cfg文件初始化。

這是造成這個問題。

變化後:

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

TO:

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

問題得到了解決。

相關問題