【问题标题】:Storing certificates in pkcs11 keystore在 pkcs11 密钥库中存储证书
【发布时间】:2013-03-30 14:01:32
【问题描述】:

我在 pkcs11 密钥库中生成一个 RSA 密钥对,它存储到智能卡中,我正在生成 pkcs10 请求。当我下载等效证书时,我如何将其存储到智能卡中(没有私钥,因为密钥已经存储在智能卡中),因为我无法访问 pkcs11 密钥库中的私钥。

    String wdtokenpath = "path to dll file";
    String pkcs11ConfigSettings = "name = SmartCard\n" + "library =" + wdtokenpath;
    byte[] pkcs11ConfigBytes = pkcs11ConfigSettings.getBytes();
    ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigBytes);
    Provider pkcs11Provider = null;

    Class sunPkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
    Constructor pkcs11Constr = sunPkcs11Class.getConstructor(
            java.io.InputStream.class);
    pkcs11Provider = (Provider) pkcs11Constr.newInstance(confStream);
    CallbackHandler call = new TextCallbackHandler();
    Subject token = new Subject();
    AuthProvider aprov = (AuthProvider) pkcs11Provider;
    aprov.login(token, call);

    System.out.println("Login successfully");
    KeyPairGenerator keyGen1 = KeyPairGenerator.getInstance("RSA", aprov);
    keyGen1.initialize(2048);
    KeyPair pair1 = keyGen1.generateKeyPair();
    PublicKey publicKey1 = pair1.getPublic();

    String sigAlg = "SHA1withRSA";
    PKCS10 pkcs10 = new PKCS10(publicKey1);
    Signature signature = Signature.getInstance("SHA1withRSA", pkcs11Provider);
    signature.initSign(pair1.getPrivate());

【问题讨论】:

    标签: rsa smartcard private-key pkcs#11 key-pair


    【解决方案1】:

    这取决于您拥有哪种智能卡,或者您拥有哪种 PKCS#11 设备。实现可能会有所不同。

    当你使用SunPKCS11时,你可以这样做:

    public boolean uploadCertificate(X509Certificate cert, String label, String id) {
            CK_ATTRIBUTE[] certificate = new CK_ATTRIBUTE[9];
    
            certificate[0] = new CK_ATTRIBUTE(PKCS11Constants.CKA_CLASS, PKCS11Constants.CKO_CERTIFICATE);
            certificate[1] = new CK_ATTRIBUTE(PKCS11Constants.CKA_TOKEN, true);
            certificate[2] = new CK_ATTRIBUTE(PKCS11Constants.CKA_PRIVATE, false);
            certificate[3] = new CK_ATTRIBUTE(PKCS11Constants.CKA_LABEL, label.toCharArray());
            certificate[4] = new CK_ATTRIBUTE(PKCS11Constants.CKA_SUBJECT, cert.getSubjectX500Principal().getEncoded());
            certificate[5] = new CK_ATTRIBUTE(PKCS11Constants.CKA_ID, HexUtils.hexStringToByteArray(id));
            certificate[6] = new CK_ATTRIBUTE(PKCS11Constants.CKA_ISSUER, cert.getIssuerX500Principal().getEncoded());
            certificate[7] = new CK_ATTRIBUTE(PKCS11Constants.CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray());
    
            try {
                certificate[8] = new CK_ATTRIBUTE(PKCS11Constants.CKA_VALUE, cert.getEncoded());
                p11.C_CreateObject(hSession, certificate);
            } catch (Exception e) {
                logger.log(Level.SEVERE, "Upload Certificate Exception", e);
                return false;
            }
    
            return true;
        }
    

    或使用 IAIK PKCS#11 Wrapper:

    // create certificate object template
            X509PublicKeyCertificate pkcs11X509PublicKeyCertificate = new X509PublicKeyCertificate();
    
            pkcs11X509PublicKeyCertificate.getToken().setBooleanValue(Boolean.TRUE);
            pkcs11X509PublicKeyCertificate.getPrivate().setBooleanValue(Boolean.FALSE);
            pkcs11X509PublicKeyCertificate.getLabel().setCharArrayValue("test".toCharArray());
            pkcs11X509PublicKeyCertificate.getSubject().setByteArrayValue(cert.getSubjectX500Principal().getEncoded());
            pkcs11X509PublicKeyCertificate.getId().setByteArrayValue(objectId);
            pkcs11X509PublicKeyCertificate.getIssuer().setByteArrayValue(cert.getIssuerX500Principal().getEncoded());
            // serial number should be an DER encoded ASN.1 integer
            /*
             INTEGER asn1Integer = new INTEGER(userCertificate.getSerialNumber());
             ByteArrayOutputStream buffer = new ByteArrayOutputStream();
             DerCoder.encodeTo(asn1Integer, buffer);
             pkcs11X509PublicKeyCertificate.getSerialNumber().setByteArrayValue(buffer.toByteArray());
             */
            // Netscape deviates from the standard here, for use with Netscape rather use
            pkcs11X509PublicKeyCertificate.getSerialNumber().setByteArrayValue(cert.getSerialNumber().toByteArray());
            pkcs11X509PublicKeyCertificate.getValue().setByteArrayValue(cert.getEncoded());
    
            session.createObject(pkcs11X509PublicKeyCertificate);
    

    证书对象的 ID 应与生成的密钥的 ID 相同。

    【讨论】:

    • 我可以编辑您的答案并使用 libpkcs11 库添加 C 代码(针对 C 程序员)吗?
    猜你喜欢
    • 2011-11-09
    • 2014-05-21
    • 2013-05-27
    • 2016-03-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多