2016-05-13 7 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 

はコードです。この問題の

根本原因はsunpkcs11プロバイダが両方読み込まなっていたということでした。私は解決方法

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

静的かつ動的に

つまり、java.securityの には、プロバイダエントリとcfgパスが既に追加されています。

また、コードでは、プロバイダーはcfgファイルで再度初期化されました。

これは問題を引き起こしていました。変更後

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

はTO:

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

問題が解決しました。

関連する問題