具有iText和eTPKCS11.dll和SunPKCS11提供程序的PKCS#11签名

时间:2018-08-31 12:46:55

标签: java authentication digital-signature pkcs#11 sunpkcs11

尝试使用链接到eTPKCS11.dll的SunPKCS11提供程序进行签名时遇到问题。即使使用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

1 个答案:

答案 0 :(得分:0)

我相信您缺少登录位。

providerPKCS11.login(null, YourCallbackHandler)