2014-04-23 3 views
1

Je voudrais signer un pdf avec itext et une carte à puce. Si je mets la carte à puce dans le lecteur, Windows ajoute automatiquement deux certificats dans le magasin. Je lis le livre de Bruno Lowagie et j'ai essayé de faire un exemple d'ajouter une image et quelques autres trucs:IText - Signer un document avec le magasin de certificats Windows

public static void main(String[] args) 
     throws GeneralSecurityException, IOException, DocumentException { 

    BouncyCastleProvider provider = new BouncyCastleProvider(); 
    Security.addProvider(provider); 

    KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); 
    //KeyStore ks = KeyStore.getInstance("PKCS11"); 
    ks.load(null, PASSWORD); 
    String alias = (String) ks.aliases().nextElement(); 
    PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD); 
    Certificate[] chain = ks.getCertificateChain(alias); 

    sign(SRC, String.format(DEST, 1), chain, pk, DigestAlgorithms.SHA256, 
      provider.getName(), CryptoStandard.CMS, "Test 1", "Ghent", "signHere"); 
    sign(SRC, String.format(DEST, 2), chain, pk, DigestAlgorithms.SHA512, 
      provider.getName(), CryptoStandard.CMS, "Test 2", "Ghent", "signHere"); 
    sign(SRC, String.format(DEST, 3), chain, pk, DigestAlgorithms.SHA256, 
      provider.getName(), CryptoStandard.CADES, "Test 3", "Ghent", "signHere"); 
    sign(SRC, String.format(DEST, 4), chain, pk, DigestAlgorithms.RIPEMD160, 
      provider.getName(), CryptoStandard.CADES, "Test 4", "Ghent", "signHere"); 
} 

public static void sign(String src, String dest, Certificate[] chain, PrivateKey pk, 
     String digestAlgorithm, String provider, CryptoStandard subfilter, 
     String reason, String location, String fieldToSign) 
     throws GeneralSecurityException, IOException, DocumentException { 

    // Creating the reader and the stamper 
    PdfReader reader = new PdfReader(src); 
    FileOutputStream os = new FileOutputStream(dest); 
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); 

    // Creating the appearance 
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); 
    appearance.setReason(reason); 
    appearance.setLocation(location); 
    appearance.setVisibleSignature(fieldToSign); 
    appearance.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_FORM_FILLING_AND_ANNOTATIONS); 

    appearance.setImage(Image.getInstance(Params.imgPath)); 
    appearance.setImageScale(-1); 

    // Creating the signature 
    ExternalDigest digest = new BouncyCastleDigest(); 
    ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider); 

    MakeSignature.signDetached(appearance, digest, signature, chain, null, null, null, 0, subfilter); 

} 

mais ce que je reçois est un java.security.InvalidKeyException: clé fournie (sun.security.mscapi.RSAPrivateKey) n'est pas une instance de RSAPrivateKey

Pourquoi sun.security.mscapi.RSAPrivateKey n'est pas une instance de RSAPrivateKey? Qu'est-ce que je fais mal ici? J'ai cette erreur avec les fichiers BouncyCastle 1.49 et 1.50

Répondre

1

Le problème est le fournisseur que vous passez lorsque vous créez la signature:

ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider); 

Le fournisseur doit être ks.getProvider() getName() (ou "SunMSCAPI") et non BouncyCastleProvider..

+0

Changer le fournisseur à "SunMSCAPI" a résolu ce problème pour moi: D: D –

0

Modifiez le nom du fournisseur en "SunMSCAPI" dans le constructeur de PrivateKeySignature.

+0

Pourquoi le downvote? C'est la solution réelle !! et a été posté avant la réponse donnée par @Rush –

Questions connexes