IText - подписать документ с хранилищем сертификатов Windows

1

Я хотел бы подписать PDF файл с itext и смарт-картой. Если я положил смарт-карту в читатель, автоматически 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);

}

но я получаю java.security.InvalidKeyException: поставляемый ключ (sun.security.mscapi.RSAPrivateKey) не является экземпляром RSAPrivateKey

Почему sun.security.mscapi.RSAPrivateKey не является экземпляром RSAPrivateKey? Что я здесь делаю неправильно? У меня есть эта ошибка как с банками BouncyCastle 1,49 и 1,50

Теги:
itext
bouncycastle

2 ответа

1
Лучший ответ

Проблема заключается в том, что вы передаете провайдер при создании подписи:

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

Поставщиком должен быть ks.getProvider(). GetName() (или "SunMSCAPI"), а не BouncyCastleProvider.

  • 0
    Смена провайдера на «SunMSCAPI» решила эту проблему для меня: D: D
0

Измените имя поставщика на "SunMSCAPI" в конструкторе PrivateKeySignature.

  • 0
    Почему отрицательный голос? это актуальное решение !! и был опубликован до ответа @Rush

Ещё вопросы

Сообщество Overcoder
Наверх
Меню