私は 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-----