Signing using PKCS#11 tokens

927 Views Asked by At

Trying to read a PKCS#11 config stream and then extract certificate and private key. It is working but when trying to create a cipher instance of the private key, getting the below error:

Exception in thread "main" java.lang.RuntimeException: Not a byte[]
at sun.security.pkcs11.wrapper.CK_ATTRIBUTE.getBigInteger(CK_ATTRIBUTE.java:153)
at sun.security.pkcs11.P11Key$P11RSAPrivateKey.fetchValues(P11Key.java:498)
at sun.security.pkcs11.P11Key$P11RSAPrivateKey.getModulus(P11Key.java:524)
at sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:289)
at sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:226)
at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:129)
at com.sun.crypto.provider.RSACipher.init(RSACipher.java:265)
at com.sun.crypto.provider.RSACipher.engineInit(RSACipher.java:210)
at javax.crypto.Cipher.implInit(Cipher.java:805)
at javax.crypto.Cipher.chooseProvider(Cipher.java:867)
at javax.crypto.Cipher.init(Cipher.java:1252)
at javax.crypto.Cipher.init(Cipher.java:1189)
at com.digio.offlinesign.test.test.main(test.java:94)

Any suggestions on how to read?

The private key is of the instance P11Key$P11RSAPrivateKey

Loading the keystore here:

    String libraryPath="name=eToken\nlibrary=" + "/usr/local/lib/wdProxKeyUsbKeyTool/libwdpkcs_ProxKey.dylib";
    ByteArrayInputStream pkcs11ConfigStream = new ByteArrayInputStream(libraryPath.getBytes());
    Class[] cArg = new Class[1];
    cArg[0] = InputStream.class;
    Class pkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
    Object providerPKCS11 = pkcs11Class.getConstructor(cArg).newInstance(new Object[] { pkcs11ConfigStream });
    Provider provider = (Provider) providerPKCS11;
    if (Security.getProvider(provider.getName())!=null){
        Security.removeProvider(provider.getName());
    }
    Security.addProvider(provider);
    java.security.KeyStore.getInstance("PKCS11");
    String password = ""; //password here for the token
    try {
        keyStore.load(null, password.toCharArray());
    } catch (Exception e) {
        e.printStackTrace();
    }

Getting the private key from the keystore:

    List<PrivateKey> privateKeyList = new ArrayList<PrivateKey>();
    String alias = null;
    PrivateKey pk = null;
    java.util.Enumeration<String> aliases = keyStore.aliases();
    while (aliases.hasMoreElements()) {
        alias = aliases.nextElement();
        pk = (PrivateKey)keyStore.getKey(alias, password.toCharArray());
        if(pk!=null)
        {
            privateKeyList.add(pk);
        }
    }

Now when creating a cipher instance here, the exception is thrown:

Cipher c = Cipher.getInstance(pk.getAlgorithm());
c.init(Cipher.ENCRYPT_MODE, pk);
0

There are 0 best solutions below