0

尝试签署文件时出现以下错误。

线程“主”org.bouncycastle.operator.OperatorCreationException 中的异常:设置异常:java.security.NoSuchAlgorithmException:没有这样的算法:org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder$1 的提供者 SunPKCS11-eToken 的 1.3.14.3.2.26。在 org.bouncycastle.cms.SignerInfoGenerator 的 org.bouncycastle.cms.SignerInfoGenerator 获取(未知来源)。(未知来源)在 org.bouncycastle.cms.SignerInfoGeneratorBuilder.createGenerator(未知来源)在 org.bouncycastle。 cms.SignerInfoGeneratorBuilder.build(Unknown Source) at org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder.build(Unknown Source) at org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder.build(Unknown Source) at testapp.Testapp.setUpProvider(Testapp. java:111) 在 testapp.Testapp。main(Testapp.java:74) 原因:java.security.NoSuchAlgorithmException:没有这样的算法:Sun.security.jca.GetInstance.getService(GetInstance.java:83) 的 sun.security.jca.GetInstance.getService(GetInstance.java:83) 的提供者 SunPKCS11-eToken 的 1.3.14.3.2.26 .security.jca.GetInstance.getInstance(GetInstance.java:202) 在 java.security.Security.getImpl(Security.java:688) 在 java.security.MessageDigest.getInstance(MessageDigest.java:233) 在 org.bouncycastle。 jcajce.ProviderJcaJceHelper.createDigest(Unknown Source) at org.bouncycastle.operator.jcajce.OperatorHelper.createDigest(Unknown Source) ... 还有 9 个 Java 结果:1java:202) at java.security.Security.getImpl(Security.java:688) at java.security.MessageDigest.getInstance(MessageDigest.java:233) at org.bouncycastle.jcajce.ProviderJcaJceHelper.createDigest(Unknown Source) at org .bouncycastle.operator.jcajce.OperatorHelper.createDigest(Unknown Source) ... 还有 9 个 Java 结果:1java:202) at java.security.Security.getImpl(Security.java:688) at java.security.MessageDigest.getInstance(MessageDigest.java:233) at org.bouncycastle.jcajce.ProviderJcaJceHelper.createDigest(Unknown Source) at org .bouncycastle.operator.jcajce.OperatorHelper.createDigest(Unknown Source) ... 还有 9 个 Java 结果:1

这是代码:

    InputStream cnfStream = new ByteArrayInputStream(pkcs11config.getBytes());
    Provider p = new sun.security.pkcs11.SunPKCS11(cnfStream);
    Security.addProvider(p);
    KeyStore ks = KeyStore.getInstance("PKCS11", p);
    ks.load(null, PASSWORD);
    byte[] signedData = sign(data, ks, p);

public static byte[] sign(byte[] data, KeyStore ks, Provider p) throws Exception {

    String alias = ks.aliases().nextElement();

    List certList = new ArrayList();
    CMSTypedData msg = new CMSProcessableByteArray(data); //Data to sign

    X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
    certList.add(cert); //Adding the X509 Certificate

    Store certs = new JcaCertStore(certList);

    CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
    //Initializing the the BC's Signer
    ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(p).build((PrivateKey)ks.getKey(alias, PASSWORD));

    gen.addSignerInfoGenerator(
            new JcaSignerInfoGeneratorBuilder(
            new JcaDigestCalculatorProviderBuilder().setProvider(p).build())
            .build(sha1Signer, cert));
    //adding the certificate
    gen.addCertificates(certs);
    //Getting the signed data
    CMSSignedData sigData = gen.generate(msg, false);
    return sigData.getEncoded();
}

任何想法?

提前致谢

4

1 回答 1

0

好的,我最终自己解决了这个问题。这是工作代码:

    private void findProvider() {
        String driver;
        byte[] pkcs11config;
        for (int i = indiceDrivers; i < largoDrivers; i++) {
            driver = DRIVERS[i];
            File f = new File(REPO + driver);
            if (!f.exists()) {
                continue;
            }
            pkcs11config = String
                    .format("name = eToken\n library = %s%s", REPO, driver)
                    .getBytes();
            try {
                InputStream cnfStream = new ByteArrayInputStream(pkcs11config);
                provider = new sun.security.pkcs11.SunPKCS11(cnfStream);
                keyStore = KeyStore.getInstance("PKCS11", this.provider);
                Security.addProvider(provider);
                keyStore.load(null, password);
                System.out.println("OK: " + driver);
                break;
            } catch (Exception e) {
                //Solo con fines de prueba
                System.out.println("ERROR: " + driver);
            }
        }
        if (provider == null) {
            throw new RuntimeException("Los drivers del token no estan instalados.");
        } else if (provider != null && keyStore == null) {
            throw new RuntimeException("El token no esta conectado.");
        }
    }

 public void sign(File input, File output) throws Exception {
        String alias = keyStore.aliases().nextElement();
        List certList = new ArrayList();
        CMSTypedData msg = new CMSProcessableFile(input);
        X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias);
        certList.add(cert);
        Store certs = new JcaCertStore(certList);
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider(provider).build((PrivateKey) keyStore.getKey(alias, password));
        Security.addProvider(new BouncyCastleProvider());
        gen.addSignerInfoGenerator(
                new JcaSignerInfoGeneratorBuilder(
                new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
                .build(sha1Signer, cert));
        gen.addCertificates(certs);
        CMSSignedData sigData = gen.generate(msg, true);

        FileOutputStream fileOuputStream = new FileOutputStream(output);
        fileOuputStream.write(sigData.getEncoded());
        fileOuputStream.flush();
        fileOuputStream.close();
    }
于 2013-02-04T17:53:08.900 回答