2016-05-13 2 views
2

Erreur reçue lors du déchiffrement des données lorsque la clé privée est extraite du HSM.Erreur HSM | La clé privée doit être une instance de clé RSAPrivate (Crt) ou avoir PKCS # 8

J'ai ajouté le fournisseur sunpkcs11 dans java.security. Par conséquent, ne pas ajouter de fournisseur via le code. Le texte est chiffré avec succès. Cependant, alors que le texte crypté à décrypter, je reçois ci-dessous erreur au-dessous de la ligne:

cipher.init(Cipher.DECRYPT_MODE, privateKey); 

Qu'est-ce que je suis absent ici?

Erreur:

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 

est Ci-dessous le code:

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

} 

Répondre

5

Comment je résolus:

causes profondes de ce problème est que le fournisseur de sunpkcs11 était obtenir chargé à la fois statiquement et dynamiquement.

Dans java.security, l'entrée du fournisseur avec le chemin cfg a déjà été ajoutée.

De même, dans le code, le fournisseur a été initialisé à nouveau avec le fichier cfg.

Cela était à l'origine du problème.

Après avoir changé:

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

À:

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

question mais j'ai résolu.