Closed scancmdr closed 5 months ago
I was stumbling about this as well, and I think there is a small error in SafeNetEToken.java, line 56:
String configuration = "--name=SafeNet eToken\nlibrary = \"" + library.getAbsolutePath().replace("\\", "\\\\") + "\"\n";
should be changed to:
String configuration = "--name=\"SafeNet eToken\"\nlibrary = \"" + library.getAbsolutePath().replace("\\", "\\\\") + "\"\n";
Changing this let me sign my executable just fine. Hope this helps.
@stolp Thanks, that seems to take a step further, my Java 8 output is now:
jarsigner error: java.security.ProviderException: Failed to create a SunPKCS11 provider from the configuration --name=SafeNet eToken
library = "/usr/lib/pkcs11/libeTPkcs11.so"
slot=0
But I will try some variations on that configuration
variable, as it is the config file I was using previously with jsign/jarsigner. I noticed that that line 56 is a bit inconsistent with --name=
and library=
-> no posix double hyphen in front of library
. I tried a few variations with both params, still got that same error.
I'm closer I think.
@scancmdr Please note that I only was successful using the jsign-maven-plugin to sign a windows executable yet. I was not yet successful at using the maven-jarsigner-plugin.
Using Java 21, I also added the following to .mvn/jvm.config in my project:
--add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED --add-exports jdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-exports java.base/sun.security.action=ALL-UNNAMED --add-exports java.base/sun.security.rsa=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED
@scancmdr, @stolp: Thank you for the feedback, I don't have an eToken to test, so your input is very valuable.
I've fixed the name parameter in the SunPKCS11 configuration.
The Jsign JCA provider is designed to work with the signing services such as Azure or AWS. I didn't think it could be useful for PKCS11 tokens since using the SunPKCS11 provider directly is easier. For example with the SafeNet eToken the syntax should look like this:
jarsigner -providerClass sun.security.pkcs11.SunPKCS11 \
-providerArg etoken.cfg \
-keystore NONE \
-storetype PKCS11 \
-storepass secret \
application.jar alias
I've changed JsignJcaProvider to also work with the Safenet eToken. With Java 11 and later it requires an extra parameter:
-J--add-exports -Jjdk.crypto.cryptoki/sun.security.pkcs11.wrapper=ALL-UNNAMED
Let me know how it works for you.
@ebourg: I was now able to both sign my windows binary and the jars (using the above SunPKCS11 configuration approach).
I am not sure, is it worth to switch to JsignJcaProvider for jar signing?
Thank you very much for your quick support, looking forward to a release of version 5.1.
I am not sure, is it worth to switch to JsignJcaProvider for jar signing?
I don't think it's worth switching. Using jarsigner with the SunPKCS11 provider instead of JsignJcaProvider means a simpler command line syntax and no extra jar. The only benefit of the Jsign provider is the automatic PKCS11 configuration.
@ebourg I'm still working on this, I will post my results, I'm working on two fronts:
Likely unrelated is how to get a JAR download done on Windows to see some EV cert code signature and not complain, certainly possible for exe, but not so clear for JAR files that are simply executable (ala java -jar
style).
If there is another test case I can do for jsign with my safenet etoken I'm happy to try and post my results for jsign.
If there is another test case I can do for jsign with my safenet etoken I'm happy to try and post my results for jsign
Yes please, did you manage to sign the exe files with the ETOKEN storetype, or is there still an exception?
I am successfully signing an exe file using the maven-jsign-plugin and the ETOKEN method. All is good.
@stolp great news.
I have time tomorrow, please let me post my experience with my safenet token with .exe
before we close. I've been using jsign for a long while.
My latest results for .exe files
Looks good.
+ rm -rf HOSTNAME.EXE
+ cp /tmp/HOSTNAME.EXE .
+ stat -t HOSTNAME.EXE
HOSTNAME.EXE 36864 72 81ed 1000 1000 10304 10892990 1 0 0 1705155445 1705155445 1705155445 1705155445 4096
+ md5sum HOSTNAME.EXE
e1ea6eff1f45aa136a2a2e18eacc1f73 HOSTNAME.EXE
+ java -jar lib/jsign-5.1-SNAPSHOT.jar -t http://timestamp.sectigo.com --storetype ETOKEN --storepass REDACTED -a Sectigo_REDACTED HOSTNAME.EXE
Adding Authenticode signature to HOSTNAME.EXE
+ stat -t HOSTNAME.EXE
HOSTNAME.EXE 47224 96 81ed 1000 1000 10304 10892990 1 0 0 1705155448 1705155448 1705155448 1705155445 4096
+ md5sum HOSTNAME.EXE
d62a717118589e14a7e03fe0a270c37b HOSTNAME.EXE
Windows likes it:
$ ./signtool.exe verify /pa HOSTNAME.EXE
File: HOSTNAME.EXE
Index Algorithm Timestamp
========================================
0 sha256 Authenticode
Successfully verified: HOSTNAME.EXE
+ java -jar lib/jsign-5.1-SNAPSHOT.jar -t http://timestamp.sectigo.com --storetype ETOKEN --storepass REDACTED -a Sectigo_REDACTED HOSTNAME.EXE
Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.limit(I)Ljava/nio/ByteBuffer;
at net.jsign.pe.PEFile.read(PEFile.java:172)
at net.jsign.pe.PEFile.<init>(PEFile.java:130)
at net.jsign.pe.PEFile.<init>(PEFile.java:114)
at net.jsign.pe.PEFile.isPEFile(PEFile.java:95)
at net.jsign.Signable.of(Signable.java:141)
at net.jsign.SignerHelper.sign(SignerHelper.java:374)
at net.jsign.JsignCLI.execute(JsignCLI.java:133)
at net.jsign.JsignCLI.main(JsignCLI.java:40)
I've seen this before, its not obvious from javadoc, but I believe the contract of some ByteBuffer methods changed in Java 9+ (returning ByteBuffer instead of Buffer, or vice versa). See this Apache issue. This could be related.
+ jarsigner -J-cp -Jlib/jsign-5.1-SNAPSHOT.jar:/opt/java8/lib/tools.jar -verbose:all -providerClass net.jsign.jca.JsignJcaProvider -providerArg etoken.cfg -keystore NONE -storetype PKCS11 -storepass REDACTED HOSTNAME.EXE Sectigo_REDACTED
jarsigner error: java.lang.IllegalArgumentException: keystore parameter should either refer to the SunPKCS11 configuration file or to the name of the provider configured in jre/lib/security/java.security
I need to adjust the command line here, can't recall.
Exception in thread "main" java.lang.NoSuchMethodError: java.nio.ByteBuffer.limit(I)Ljava/nio/ByteBuffer;
This is a common issue, building Jsign with Java 8 will fix it.
jarsigner -J-cp -Jlib/jsign-5.1-SNAPSHOT.jar:/opt/java8/lib/tools.jar -verbose:all -providerClass net.jsign.jca.JsignJcaProvider -providerArg etoken.cfg -keystore NONE -storetype PKCS11 -storepass REDACTED HOSTNAME.EXE Sectigo_REDACTED jarsigner error: java.lang.IllegalArgumentException: keystore parameter should either refer to the SunPKCS11 configuration file or to the name of the provider configured in jre/lib/security/java.security
Try this syntax instead (with a .jar file, not a .exe):
jarsigner -J-cp -Jlib/jsign.jar:/opt/java8/lib/tools.jar \
-providerClass net.jsign.jca.JsignJcaProvider \
-keystore NONE \
-storetype ETOKEN \
-storepass secret \
application.jar alias
Yes that worked with Java 8:
$ jarsigner -tsa http://timestamp.sectigo.com \
-J-cp -Jlib/jsign-5.1-SNAPSHOT.jar:/opt/java8/lib/tools.jar \
-providerClass net.jsign.jca.JsignJcaProvider \
-keystore NONE \
-storetype ETOKEN \
-storepass REDACTED \
geek.jar Sectigo_REDACTED
jar signed.
The signer certificate will expire on 2026-12-24.
The timestamp will expire on 2034-08-02.
$ jarsigner -verify geek.jar
jar verified.
I was able to sort my intermediate cert issue by importing them into my etoken using the safenet config tool. @ebourg thanks very much for your help!
@scancmdr Thank you for checking!
I'm trying to sign a JAR file with a SafeNet etoken. I have the proper setup (latest safenet software, can list and sign exe files just fine with jsign). I've build jsign from the master branch and am using that jar.
I've read https://github.com/ebourg/jsign/discussions/178 and the docs at https://ebourg.github.io/jsign/#jca-provider
Java 8 using storetype ETOKEN
note: the pkcs libraries are simlinks to each other (
/usr/lib/pkcs11/libeTPkcs11.so -> ../libeTPkcs11.so
)Java 8 using storetype PKCS11
where etoken.cfg is:
Java 11 & 17 using storetype ETOKEN