首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PKCS11 inJAVA创建PKCS10证书请求

使用PKCS11 inJAVA创建PKCS10证书请求
EN

Stack Overflow用户
提问于 2013-11-26 21:52:41
回答 1查看 5.3K关注 0票数 3

我必须为存储在cryptocard上的RSA密钥对创建PKCS10证书请求,并通过PKCS11接口访问。问题是我不能在PKCS10创建过程中使用标准的RSA算法,也不能从cryptocard获取私钥,所以加密操作应该在CRYPTOCard端完成。如何使用PKCS11接口准备(可能是手动) PKCS10请求以进行签名?

@Edit Now我有一个类似这样的错误:

代码语言:javascript
复制
Exception in thread "main" java.security.ProviderException: Initialization failed
    at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:310)
    at sun.security.pkcs11.P11Signature.engineInitSign(P11Signature.java:391)
    at java.security.Signature$Delegate.engineInitSign(Signature.java:1127)
    at java.security.Signature.initSign(Signature.java:511)
    at pkcs11.Main.stworzPkcs10(Main.java:65)
    at pkcs11.Main.main(Main.java:53)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_GENERAL_ERROR
    at sun.security.pkcs11.wrapper.PKCS11.C_SignInit(Native Method)
    at sun.security.pkcs11.P11Signature.initialize(P11Signature.java:302)
    ... 5 more
Java Result: 1

和代码:

代码语言:javascript
复制
    String zawartoscPlikuKonfiguracyjnego = new String(
            "name=PKCS11\n" +
            "library=" + sciezkaDoBibliotekiPkcs11);

    FileOutputStream plikKonfiguracyjny = new FileOutputStream("pkcs11.cfg");
    plikKonfiguracyjny.write(zawartoscPlikuKonfiguracyjnego.getBytes());
    plikKonfiguracyjny.close();

    File test = new File("pkcs11.cfg");
    dostawcaPkcs11 = new SunPKCS11("pkcs11.cfg");
    Security.addProvider(dostawcaPkcs11);

    interfejsPkcs11 = KeyStore.getInstance("PKCS11",dostawcaPkcs11);        
    pin = new JPasswordField();
    JOptionPane.showConfirmDialog(null, pin, "Podaj pin do tokena", JOptionPane.OK_CANCEL_OPTION);

    interfejsPkcs11.load(null, pin.getPassword());

    Key kluczPrywatny = null;
    Key kluczPubliczny = null;

    Enumeration<String> aliasy = interfejsPkcs11.aliases();
    while(aliasy.hasMoreElements()) {
        String alias = aliasy.nextElement();
        if(interfejsPkcs11.isKeyEntry(alias)) {
            kluczPrywatny = interfejsPkcs11.getKey(alias, pin.getPassword());
        } else {
            kluczPubliczny = interfejsPkcs11.getCertificate(alias).getPublicKey();
        }
    }

    PKCS10 pkcs10 = new PKCS10((PublicKey) kluczPubliczny );
    Signature sygnatura = Signature.getInstance("SHA1WithRSA", dostawcaPkcs11);
    sygnatura.initSign((PrivateKey) kluczPrywatny);
    X500Name nazwaX500 = new X500Name("Certyfikat testowy", "Developer", "Developer", "Warszawa", "Mazovia", "PL");
    pkcs10.encodeAndSign(nazwaX500, sygnatura);
EN

回答 1

Stack Overflow用户

发布于 2013-11-26 22:18:11

我建议您尝试使用Sun PKCS#11提供程序。您需要遵循the documentation来了解如何配置提供者以使用您的cryptocard供应商提供的动态链接库。(也值得问问他们从Java访问cryptocard的推荐方法)。

一旦这个工作完成,您应该能够从密钥库加载您的公钥和私钥(请再次参阅文档了解它是如何工作的)。最后,您可以使用JCE库来生成签名请求:

代码语言:javascript
复制
String CN = "Mr Foo";
String OU = "Foo Department";
String O = "Foo Ltd.";
String L = "Foosville";
String S = "Foouisiana";
String C = "GB";

PublicKey publicKey = //... load public key from keystore
PrivateKey privateKey = //... load private key from keystore

PKCS10 pkcs10 = new PKCS10(publicKey);
Signature signature = Signature.getInstance("SHA1WithRSA"); // or whatever
signature.initSign(privateKey);    
X500Name x500Name = new X500Name(CN, OU, O, L, S, C);
pkcs10.encodeAndSign(new X500Signer(signature, x500Name));

try (ByteArrayOutputStream bs = new ByteArrayOutputStream(); 
     PrintStream ps = new PrintStream(bs)) {
  pkcs10.print(ps);
  byte[] c = bs.toByteArray(); // <-- this is it! (save to disk maybe?)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20218952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档