0

我在尝试使用链接到 eTPKCS11.dll 的 SunPKCS11 Provider 进行签名时遇到问题。即使使用 iText signDetached,在尝试简单签名时,我也总是得到“线程中的异常”java.security.ProviderException:sun.security.pkcs11.wrapper.PKCS11Exception:CKR_USER_NOT_LOGGED_IN”。

我成功获得PK,通过回调完成认证,回调直接返回令牌密码。似乎令牌需要另一个身份验证过程来进行签名?

该设备是SafeNet eToken 5110,运行在Win7 64位...

非常感谢!

public class Main {

    public static Properties properties = new Properties();

    public static void main(String args[]) throws IOException, GeneralSecurityException, DocumentException
        {
        String userFile = "E:/plain.pdf";
        String userFile_signed = "E:/plain-tsig.pdf";

        String pkcs11Config = "name=eToken\nlibrary=C:\\Windows\\System32\\eTPKCS11.dll\nshowInfo=true";
        java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes());
        sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(pkcs11ConfigStream);

        java.security.Security.addProvider(providerPKCS11);
        String pin = "PIN-1234";

        KeyStore.CallbackHandlerProtection chp = new KeyStore.CallbackHandlerProtection(new MyGuiCallbackHandler() {});
        KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", null, chp);

        KeyStore keyStore = builder.getKeyStore();
        java.util.Enumeration<String> aliases = keyStore.aliases();
        String alias = null;
        while (aliases.hasMoreElements()) {
            alias = aliases.nextElement();
            System.out.println(alias);
        }
        System.out.println(providerPKCS11.getName());
        PrivateKey pk = (PrivateKey) keyStore.getKey(alias, null);


        Certificate[] chain = keyStore.getCertificateChain(alias);
        OcspClient ocspClient = new OcspClientBouncyCastle();
        TSAClient tsaClient = null;
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = (X509Certificate)chain[i];
            String tsaUrl = CertificateUtil.getTSAURL(cert);
            if (tsaUrl != null) {
                tsaClient = new TSAClientBouncyCastle(tsaUrl);
                break;
            }
        }
        List<CrlClient> crlList = new ArrayList<CrlClient>();
        crlList.add(new CrlClientOnline(chain));
        Main t = new Main();
        System.out.println(providerPKCS11.getServices().toString());

        Signature signer = Signature.getInstance("SHA256withRSA", keyStore.getProvider());
        signer.initSign(pk);
        String data = "Hello world......";
        signer.update(data.getBytes()); 
        byte[] signedData = signer.sign();        
        System.out.println(signedData.toString());

        providerPKCS11.logout();
}

    private static abstract class MyGuiCallbackHandler implements CallbackHandler {

        public MyGuiCallbackHandler() {
            System.out.println("Sending PIN from callback...");
        }

        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (int i = 0; i < callbacks.length; i++) {
                PasswordCallback pc = (PasswordCallback) callbacks[i];
                String pin = "PIN-1234";
                pc.setPassword(pin.toCharArray());
            }
        }
}

}

结果:

run:
SunPKCS11 loading ---DummyConfig-1---
sunpkcs11: Initializing PKCS#11 library C:\Windows\System32\eTPKCS11.dll
Information for provider SunPKCS11-eToken
Library info:
  cryptokiVersion: 2.20
  manufacturerID: SafeNet, Inc.                   
  flags: 0
  libraryDescription: SafeNet eToken PKCS#11          
  libraryVersion: 10.04
All slots: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
Slots with tokens: 0
Slot info for slot 0:
  slotDescription: AKS ifdh 0                                                      
  manufacturerID: SafeNet, Inc.                   
  flags: CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT
  hardwareVersion: 1.00
  firmwareVersion: 0.00
Token info for token in slot 0:
  label: ****               
  manufacturerID: Gemalto                         
  model: ID Prime MD     
  serialNumber: ****
  flags: CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_DUAL_CRYPTO_OPERATIONS | CKF_TOKEN_INITIALIZED
  ulMaxSessionCount: CK_EFFECTIVELY_INFINITE
  ulSessionCount: 0
  ulMaxRwSessionCount: CK_EFFECTIVELY_INFINITE
  ulRwSessionCount: 0
  ulMaxPinLen: 16
  ulMinPinLen: 4
  ulTotalPublicMemory: 32768
  ulFreePublicMemory: 25882
  ulTotalPrivateMemory: 32768
  ulFreePrivateMemory: 25882
  hardwareVersion: 16.00
  firmwareVersion: 16.01
...
PKCS#11 Provider ->SunPKCS11-eToken using library C:\Windows\System32\eTPKCS11.dll
Sending PIN from callback
sunpkcs11: login succeeded
iSignum 00000000-000000
...
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:591)
    at java.security.Signature$Delegate.engineSign(Signature.java:1207)
    at java.security.Signature.sign(Signature.java:579)
    at TSTgo.Main.main(Main.java:146)
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_USER_NOT_LOGGED_IN
    at sun.security.pkcs11.wrapper.PKCS11.C_SignFinal(Native Method)
    at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:553)
    ... 3 more
4

1 回答 1

0

我相信您缺少登录位。

providerPKCS11.login(null, YourCallbackHandler)

于 2018-08-31T13:18:42.270 回答