2

我一直在试验 SafeNet (Aladdin) eToken 和 Java 8 的 PKCS11 接口。我注意到,当我调试以下代码片段时,它会起作用。如果我在没有调试器的情况下运行它,我会遇到异常。我引入了人为的延迟,突然它在没有调试器的情况下工作。这让我相信我的代码中存在竞争条件。有没有更好的方法来做到这一点?或者这是否特定于我的令牌?或者这是基于 debian 的系统的 Java 8 x64 中的一个新错误?

public class CertificteRequestTest {

  public static void main(String[] args) throws Exception{

    KeyStore keyStore = getPKCS11Keys();
    PrivateKey privateKey = (PrivateKey)keyStore.getKey("onekey",null);
    PublicKey publicKey = ((KeyStore.PrivateKeyEntry)keyStore.getEntry("onekey",null)).getCertificate().getPublicKey();

    X500Principal principal = new X500Principal("CN=onesubject");

    PKCS10CertificationRequestBuilder builder
        = new JcaPKCS10CertificationRequestBuilder(principal,publicKey);
    ContentSigner signer
        = new JcaContentSignerBuilder("SHA256withRSA").build(privateKey);

    /* Removing this causes the Signer to think the token is not logged in */
    Thread.sleep(1000);

    PKCS10CertificationRequest csr = builder.build(signer);
    PEMWriter writer = new PEMWriter(new PrintWriter(System.out));
    writer.writeObject(csr);
    writer.close();
  }

  public static KeyStore getPKCS11Keys() throws KeyStoreException {
    SunPKCS11 provider = new SunPKCS11ProviderFactory()
        .withDescription("PKCS11TestProvider - libeToken 8")
        .withName("PKCS11TestProvider")
        .withLibrary("/lib64/libeToken.so.8").build();
    Security.addProvider(provider);
    KeyStore.CallbackHandlerProtection pinHandler
        = new KeyStore.CallbackHandlerProtection(new TextCallbackHandler());
    return KeyStore.Builder.newInstance("PKCS11",provider,pinHandler).getKeyStore();
  }
}

抛出的异常似乎表明我没有登录令牌,但我已经登录了。输入错误的 PIN 会导致登录尝试失败。

$ java ... com.test.CertificteRequestTest
PKCS11 Token [SunPKCS11-PKCS11TestProvider] Password:
Exception in thread "main" java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_USER_NOT_LOGGED_IN
        at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:588)
        at java.security.Signature$Delegate.engineSign(Signature.java:1162)
        at java.security.Signature.sign(Signature.java:554)
        at org.bouncycastle.operator.jcajce.JcaContentSignerBuilder$SignatureOutputStream.getSignature(Unknown Source)
        at org.bouncycastle.operator.jcajce.JcaContentSignerBuilder$1.getSignature(Unknown Source)
        at org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder.build(Unknown Source)
        ...
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_USER_NOT_LOGGED_IN
        at sun.security.pkcs11.wrapper.PKCS11.C_Sign(Native Method)
        at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:579)

安装人工延迟后,这是成功运行的结果:

$ java ... com.test.CertificteRequestTest
PKCS11 Token [SunPKCS11-PKCS11TestProvider] Password:
-----BEGIN CERTIFICATE REQUEST-----
MIICW...
-----END CERTIFICATE REQUEST-----
4

0 回答 0