Using PKCS11 Credentials
xmlsectool
supports using credentials stored in PKCS#11 tokens such as cryptographic smart cards, both to sign and verify documents.
To do this, it makes use of the Java runtime's ability to present an external PKCS#11 token as a Java keystore as described in the PKCS#11 Reference Guide.
Not all PKCS#11 implementations can be used in this way; in particular, tokens which do not allow an X.509 certificate to be stored alongside the private key are not compatible with the SunPKCS11 provider and thus cannot be used with xmlsectool
. This is, unfortunately, true of some (but by no means all) high-end hardware security modules (HSMs).
A compatible PKCS#11 implementation must be configured into the SunPKCS11 provider as described in the PKCS#11 Reference Guide. This requires providing a simple configuration file, such as the following example:
name=acs
library=/path/to/library.so
description=ACOS5 token
This configuration can be provided in one of two ways:
Statically, by editing the
java.security
file within the Java runtime, orDynamically, by providing it to
xmlsectool
's--pkcs11Config
option.
Although xmlsectool
supports both options, we strongly recommend dynamic configuration over static: because static configuration requires you to change a file within the Java runtime itself, the changes apply to every application using that runtime, require additional permissions on most systems, and may be erased whenever the runtime is updated.
We do not recommend mixing dynamic and static configuration (i.e., using --pkcs11Config
with a modified java.security
file, as this can cause two copies of the provider to be loaded. This may result in hard to debug errors, such as "Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding" or "No installed provider supports this key".
Using xmlsectool
with Dynamic PKCS#11 Configuration
To use a credential from a dynamically configured PKCS#11 token, use the --pkcs11Config
option as follows:
...xmlsectool.sh --pkcs11Config /path/to/config.cfg ...
For example:
...xmlsectool.sh --sign --pkcs11Config /path/to/config.cfg \
--keyAlias key2048 --keyPassword 1234 \
--inFile unsigned.xml --outFile signed.xml
Verification works in the same way:
Of course, because signature verification does not involve the private key, it may be simpler to use a file-based credential for this operation through the --certificate
option rather than using PKCS#11.
Using xmlsectool
with Static PKCS#11 Configuration
If for some reason you can not use the recommended dynamic PKCS#11 configuration, xmlsectool
also supports static configuration of your PKCS#11 provider.
As described in the PKCS#11 Reference Guide, one way to do this is to modify the JDK's java.security
file. Add a new configured security provider to the end of the list, after the unconfigured SunPKCS11 provider, like this:
(Alternatively, you can augment or override the JDK's java.security
file, see below.)
The number of providers in the distributed java.security
file may vary between Java versions and between platforms: the list should always end with a SunPKCS11
entry; your configured provider should be added after that with the next sequential index.
Once you have modified java.security
you can access PKCS#11 credentials from the new provider like this:
Here, "/dev/null
" represents the null device for your system.
For example:
Augmenting or overriding java.security
It is possible to use static PKCS#11 configuration without editing the JDK's master version of java.security
. This mechanism is documented in the master java.security
file itself and involves adding "-Djava.security.properties=<URL>
" to the command line; refer to java.security
for full details.
The indicated local file can be used to either supplement or override the master java.security
file. You can add extra JVM options to the xmlsectool
command line like this:
For example:
As described in java.security
, the above example augments the JDK's version of java.security
; it might just contain a single line:
Alternatively, you can override the master version of java.security
entirely by using ==
instead of =
like this:
I this case, local-java.security
must include the complete configuration normally found in the master version of java.security
.
Upgrading from a previous version of xmlsectool
In Java 9, a change was made to the way security providers such as the SunPKCS11 provider are handled, and in particular configured. This has necessarily resulted in changes to the way xmlsectool
provides this functionality.
If in a previous version of xmlsectool
you used a command line with both --pkcs11Config
and --keystoreProvider
options, like this:
... you will now receive the following warning message:
You should update your command line to omit the --keystoreProvider
option in this case. This will become an ERROR in a future version of xmlsectool
.
If in a previous version of xmlsectool
you used a command line with a dummy --pkcs11Config
option and no --keystoreProvider
option, like this:
... you will now receive an error message saying that the file DUMMY does not exist:
This old style of static configuration is equivalent to the "--keystore /dev/null --keystoreType PKCS11
" mechanism described above, and you should update your command line accordingly.