rsa - 将证书存储在 pkcs11 keystore 中

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

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

    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());

最佳答案

这取决于您拥有哪种智能卡,或者您拥有哪种 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 包装器:

// 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应与生成的 key 的ID相同。

关于rsa - 将证书存储在 pkcs11 keystore 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15879938/

相关文章:

java - 错误:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

java.security.spec.InvalidKeySpecException : java. security.InvalidKeyException : IOException : DER input, 整数标记错误

ssh - jenkins ssh 代理转发

java - 在调用 doFinal 之前检查 RSA key 是否正确?

c++ - 开始智能卡编程

java - 我在哪里可以保存java代码中使用的私钥

smartcard - Cryptoki C_Initialize 失败,代码为 0x5

android - UICC : Can I trust proactive TIMER MANAGEMENT?

private-key - 如何从私钥中获取助记词钱包 key (12个单词)?

php - 在移动客户端和服务器 PHP 之间使用公钥/私钥进行加密