Closed malmor closed 7 months ago
Hi @malmor, thanks for reaching out, we'll have eyes on this soon. @backwind1233, @chenrujun can you take a look or route it to the right person? Thanks!
Hey @vcolin7, thanks for the initial triage. Just wanted to check in - do you have any update or timeline on this? Finding a solution for this use-case would help us a lot! Regards, Malte
Hi @malmor , Thank you for reporting this issue. We have received your submission and will take it into consideration. We appreciate your input and will review this matter as soon as possible. Please feel free to provide any additional information or context that you think may be helpful. We'll keep you updated on the progress of our review. Thank you for your contribution to improving our project.
Hi,
Do we have a resolution on this?
Hi @schannaveera1 Thanks for reaching out.
@schannaveera1 @malmor Could you refer to this guide integrate_keyvault_JCA_provider_with_jarsigner.md to use jarsigner with KeyVaultJcaProvider.
Please reply here if it works for you..
Hey @backwind1233, thanks for writing the documentation!
I will give it a try and keep you posted!
Hello @malmor, do you have any update, does it work for you?
Hello @backwind1233, sorry for the delay. I just tried the steps you documented - but they do not seem to work.
What I did:
openjdk v19
- which no longer supports the ${JAVA_HOME}/jre/lib/ext
folder (as far as I know)java.security
file and replaced it at C:\Program Files\OpenJDK\jdk-19.0.1\conf\security\java.security
security.provider.12=SunMSCAPI
security.provider.13=SunPKCS11
security.provider.14=com.azure.security.keyvault.jca.KeyVaultJcaProvider
jarsigner
with the documented flags
storepass
needs to contain a space š¤·āāļøjarsigner ^
-keystore NONE ^
-storetype AzureKeyVault ^
-signedjar signerjar.jar ^
maven-filtering-3.3.0.jar ^
"my-code-signing-certificate" ^
-verbose ^
-storepass ' ' ^
-providerPath C:\test\azure-security-keyvault-jca.jar ^
-providerName AzureKeyVault ^
-providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider ^
-J'-Dazure.keyvault.uri=https://my-vault.vault.azure.net/' ^
-J'-Dazure.keyvault.tenant-id=my-tenant-id' ^
-J'-Dazure.keyvault.client-id=my-client-id' ^
-J'-Dazure.keyvault.client-secret=my-client-secret'
Here are the logs:
If I can provide any additional information to help troubleshooting this please ask.
Regards, Malte
@malmor Thank you for your feedback.
@moarychan could you help try this with you machine? We can discuss about it later. cc: @saragluna
Hi, I've installed com.azure:azure-security-keyvault-jca:2.7.1 on Oracle JDK 1.8.0_u361, tried out the jarsigner command below and got an error different from the OP. We've contacted MS Support and they directed us back to this issue tracker.
"C:\Program Files\Java\jdk1.8.0_361\bin\jarsigner.exe" -keystore NONE -storetype AzureKeyVault -signedjar my-signed-jar.jar my-jar.jar -verbose -storepass "" -providerName AzureKeyVault -providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider -J-Dazure.keyvault.uri="\<keyvault-uri>" -J-Dazure.keyvault.tenant-id="\<tenant-id>" -J-Dazure.keyvault.client-id="\<client-id>" -J-Dazure.keyvault.client-secret="\<client-secret>" "\<cert alias>"
jarsigner error: java.lang.RuntimeException: private key is not a DSA or RSA key
Looking at the public key in the certificate properties, it shows RSA(3072 Bits). Any clue of what to look into next? I believe the private key is also not exportable in our scenario.
@malmor may I ask about your certificate advanced policy configuration?
@jyuenatsolarsoft what's your certificate advanced policy configuration?
@malmor may I ask about your certificate advanced policy configuration?
Hey @saragluna, we used to following settings:
Extended Key Usages
: 1.3.6.1.5.5.7.3.3X.509 Key Usage Flags
: Digital SignatureReuse Key on Renewal?
: NoExportable Private Key?
: NoKey Type
: RSA-HSMKey Size
: 3072Enable Certificate Transparency?
: YesCertificate Type
: emptyIf there are any other settings that could be interesting please ask. Thanks!
@saragluna Here's the advanced policy configuration. Let us know if you need more info.
Hello @jyuenatsolarsoft In jarsigner official doc, it supports DSA, RSA and ECDSA by default. You can check here
From your log, it seems the jarsigner just can't identify the RSA-HSM
as RSA
.
So,
-sigalg
flag?
RSA-HSM
is the same with RSA
, is SHA256withRSA.@backwind1233 @saragluna
That's not an option. There is a new certificate storage requirement from the industry. The private key cannot leave the HSM, so we cannot try with RAS instead of RSA-HSM. https://knowledge.digicert.com/generalinformation/new-private-key-storage-requirement-for-standard-code-signing-certificates-november-2022.html
I got the following error after adding -sigalg SHA256withRSA to the command. jarsigner error: java.security.SignatureException: private key algorithm is not compatible with signature algorithm
@malmor and @jyuenatsolarsoft
I agree that the issue lies in the HSM part, I think the current code doesn't support RSA-HSM or EC-HSM. I created this draft PR https://github.com/Azure/azure-sdk-for-java/pull/36648, maybe you guys can help run the JarSignerSample
directly to check whether it works with your certificate. With this code, you can debug and see what's wrong.
My initial thought is to change the key type from RSA-HSM
to RSA
in the KeyVaultClient
, because the JarSigner will throw an exception when the algorithm doesn't match:
/**
* Creates a {@code JarSigner.Builder} object with a private key and
* a certification path.
*
* @param privateKey the private key of the signer.
* @param certPath the certification path of the signer.
* @throws IllegalArgumentException if {@code certPath} is empty, or
* the {@code privateKey} algorithm does not match the algorithm
* of the {@code PublicKey} in the end entity certificate
* (the first certificate in {@code certPath}).
*/
public Builder(PrivateKey privateKey, CertPath certPath) {
List<? extends Certificate> certs = certPath.getCertificates();
if (certs.isEmpty()) {
throw new IllegalArgumentException("certPath cannot be empty");
}
if (!privateKey.getAlgorithm().equals
(certs.get(0).getPublicKey().getAlgorithm())) {
throw new IllegalArgumentException
("private key algorithm does not match " +
"algorithm of public key in end entity " +
"certificate (the 1st in certPath)");
}
If not alg specified, the JarSigner will call SignatureUtil.getDefaultSigAlgForKey
to construct the default sig alg for a given key,
public static String getDefaultSigAlgForKey(PrivateKey k) {
String kAlg = k.getAlgorithm().toUpperCase(Locale.ENGLISH);
return switch (kAlg) {
case "DSA" -> "SHA256withDSA";
case "RSA" -> ifcFfcStrength(KeyUtil.getKeySize(k)) + "withRSA";
case "EC" -> ecStrength(KeyUtil.getKeySize(k)) + "withECDSA";
case "EDDSA" -> k instanceof EdECPrivateKey
? ((EdECPrivateKey) k).getParams().getName()
: kAlg;
case "RSASSA-PSS", "ED25519", "ED448" -> kAlg;
default -> null;
};
}
In our case, it will be xxxwithRSA
. Since JDK already has built-in signature spi implementations defined in RSASignature
, so we should use our provider to override the built-in ones, which will send the content to KV to sign.
The PR is not finalized, but please take a look and try, to see whether it will work.
Hey @saragluna, thanks for looking into this and starting the PR!
I must admit I have zero to no experience with java/jarsigner. Could you outline a bit what "maybe you guys can help run the JarSignerSample directly to check whether it works with your certificate" should mean?
I will happily try this out tomorrow š
@saragluna Thanks for the prompt reply.
I have no idea how to run the JarSignerSample too. Could you elaborate on that?
@malmor and @jyuenatsolarsoft that will be a bit challenging. Could you guys let me know once you guys sign the jar, how are you going to verify it so that I can try on my side?
To make things easier for you guys to try the code, I sort-of-forked this repo https://github.com/saragluna/azure-security-kv-jca-fork/tree/main, and you guys can either build the jar directly and use the jarsigner command, or try the code in one of the IDEs.
FYI, for a key length of 3072, the alg should be -sigalg SHA512withRSA
.
@saragluna
Thanks for setting up the test repo. Appreciated.
With the JCA provider compiled from the test repo, the jarsigner command completed the signing process without errors. However, when we tried to verify the signed jar file with the command "jarsigner -verify", it returned an error indicating the jar was treated as unsigned due to a signature issue.
jar: processEntry: processing block
jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 8 but was expecting 384
jar: done with meta!
jar: nothing to verify!
WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar).
Hey @saragluna, thanks for the repo - that helped a lot!
I just tried the beta version and saw the same behaviour as @jyuenatsolarsoft:
jarsigner
works - jar signed
jarsigner
failed with an errorPS C:\test> jarsigner -verify -debug -verbose -certs -J'-Djava.security.debug=jar' signed-jar.jar
Command line args: [-verify, -debug, -verbose, -certs, signed-jar.jar]
jar: beginEntry META-INF/MANIFEST.MF
jar: beginEntry META-INF/REDACTED.SF
jar: processEntry: processing block
jar: beginEntry META-INF/REDACTED.RSA
jar: processEntry: processing block
jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 8 but was expecting 384
jar: done with meta!
jar: nothing to verify!
4748 Tue Sep 12 07:35:38 GMT+02:00 2023 META-INF/MANIFEST.MF
4678 Tue Sep 12 07:35:38 GMT+02:00 2023 META-INF/REDACTED.SF
2179 Tue Sep 12 07:35:38 GMT+02:00 2023 META-INF/REDACTED.RSA
0 Sat Jun 11 13:41:16 GMT+02:00 2022 META-INF/
0 Sat Jun 11 13:41:16 GMT+02:00 2022 META-INF/sisu/
....
- Signed by "CN=Company, OU=Company, O=Company, L=City, C=County"
Digest algorithm: SHA-384
Signature algorithm: SHA512withRSA, 3072-bit key
WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar).
Thanks @jyuenatsolarsoft and @malmor for the update, let me check whether it's because of the hash function.
Hi @jyuenatsolarsoft and @malmor, I just updated the code, maybe you guys can have another try.
@saragluna Thanks for the updates. I've been following this issue as well. I just compiled and tested. Looks encouraging.
NOTE I initially received a duplicate class error on compile and had to remove the following source file:
src/main/java/com/azure/security/keyvault/jca/implementation/signature/KeyVaultKeyLessECSignature.java
For reference I'm using a self-signed certificate with the following advanced policy config:
Extended Key Usages: 1.3.6.1.5.5.7.3.3 X.509 Key Usage flags: Digital Signature, Key Encipherment Reuse key on renewal: NO Exportable Private Key: NO Key Type: RSA-HSM Key Size: 4096 Enable Cert Transparency: NO
Here is my jarsigner command (note using debug):
/usr/bin/jarsigner \
-J-Djava.security.debug=jar \
-keystore NONE \
-sigalg SHA512withRSA \
-storetype AzureKeyVault \
-signedjar signed.jar $1 "HomeSelfSignedCert3072PKCS" \
-verbose \
-storepass ' ' \
-providerName AzureKeyVault \
-J-cp -J./azure-security-keyvault-jca-2.8.0-beta.1.jar \
-providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider \
-J'-Dazure.keyvault.uri=https://REDACTED.vault.azure.net/' \
-J'-Dazure.keyvault.tenant-id=REDACTED' \
-J'-Dazure.keyvault.client-id=REDACTED' \
-J'-Dazure.keyvault.client-secret=REDACTED'
Here is the result I was getting before your most recent commit 6bc9de2:
$ ./jcc_sign_it_now.sh unsigned.jar
Sep 12, 2023 6:51:29 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient <init>
INFO: Using Azure Key Vault: https://azpremkv.vault.azure.net/
Sep 12, 2023 6:51:29 AM com.azure.security.keyvault.jca.implementation.utils.AccessTokenUtil getAccessToken
INFO: Getting access token using client ID / client secret
Sep 12, 2023 6:51:31 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeCert3072PKCS
Sep 12, 2023 6:51:31 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeCert3072PKCS
Sep 12, 2023 6:51:31 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 6:51:32 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 6:51:32 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient <init>
INFO: Using Azure Key Vault: https://azpremkv.vault.azure.net/
Sep 12, 2023 6:51:32 AM com.azure.security.keyvault.jca.implementation.utils.AccessTokenUtil getAccessToken
INFO: Getting access token using client ID / client secret
Sep 12, 2023 6:51:32 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeCert3072PKCS
Sep 12, 2023 6:51:33 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeCert3072PKCS
Sep 12, 2023 6:51:33 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 6:51:34 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeSelfSignedCert3072PKCS
updating: META-INF/MANIFEST.MF
adding: META-INF/HOMESELF.SF
adding: META-INF/HOMESELF.RSA
signing: HelloWorld.class
jar: beginEntry META-INF/MANIFEST.MF
jar: beginEntry META-INF/HOMESELF.SF
jar: processEntry: processing block
jar: beginEntry META-INF/HOMESELF.RSA
jar: processEntry: processing block
jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 8 but was expecting 512
jar: done with meta!
jar: nothing to verify!
>>> Signer
X.509, CN=KallahanHome
[trusted certificate]
jar signed.
Warning:
The signer's certificate is self-signed.
Here is the result I am now getting after your most recent commit 6bc9de2:
$ ./jcc_sign_it_now.sh unsigned.jar
Sep 12, 2023 7:47:33 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient <init>
INFO: Using Azure Key Vault: https://azpremkv.vault.azure.net/
Sep 12, 2023 7:47:33 AM com.azure.security.keyvault.jca.implementation.utils.AccessTokenUtil getAccessToken
INFO: Getting access token using client ID / client secret
Sep 12, 2023 7:47:37 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeCert3072PKCS
Sep 12, 2023 7:47:37 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeCert3072PKCS
Sep 12, 2023 7:47:38 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 7:47:38 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 7:47:38 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient <init>
INFO: Using Azure Key Vault: https://azpremkv.vault.azure.net/
Sep 12, 2023 7:47:38 AM com.azure.security.keyvault.jca.implementation.utils.AccessTokenUtil getAccessToken
INFO: Getting access token using client ID / client secret
Sep 12, 2023 7:47:39 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeCert3072PKCS
Sep 12, 2023 7:47:39 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeCert3072PKCS
Sep 12, 2023 7:47:40 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getKey
INFO: Getting key for alias: HomeSelfSignedCert3072PKCS
Sep 12, 2023 7:47:40 AM com.azure.security.keyvault.jca.implementation.KeyVaultClient getCertificate
INFO: Getting certificate for alias: HomeSelfSignedCert3072PKCS
updating: META-INF/MANIFEST.MF
adding: META-INF/HOMESELF.SF
adding: META-INF/HOMESELF.RSA
signing: HelloWorld.class
jar: beginEntry META-INF/MANIFEST.MF
jar: beginEntry META-INF/HOMESELF.SF
jar: processEntry: processing block
jar: beginEntry META-INF/HOMESELF.RSA
jar: processEntry: processing block
jar: Signature Block Certificate: [
[
Version: V3
Subject: CN=KallahanHome
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
Key: Sun RSA public key, 4096 bits
params: null
modulus: 840838420139145776249025751413243908756506301891843392167435996527433986134554537391373344627556162132329988597681361405483119867161701371292217933003606089696934076553328976139061934109987670737510353076860603634759415798188588319887407095193677150294404744070639231768531594241258194996225820856216424226320274475557307014566807998451421008273557186165958447729313334131751046539974564895987294671649563369584440590961445418456416989881802277797225997279865141037335235614811529171299294304249123261144545672351811214898488859776066783880411485652182479126295505402114824573609608541163570770383791837700005288653079334817188310096865589596667146951135936089936943031469709622897002542908455237838389068203353168314351821270411712832835309715493732239305562439302496095714499330192425656938747760064567258992559562706371029809979566109475725948854376002806908535907638235102764823128597342856801995527019784694581745830505431923049048800631863223192119991616077850590690361681848519141342705179022975857073356001985172757705029703082948400424058673202933064018739192171811091959459626450725962311386630507946265402849902999780218730691172700461060254416357951556775705288281631498111362207775670686639994499510796765980160825571367
public exponent: 65537
Validity: [From: Tue Sep 12 06:36:30 CDT 2023,
To: Thu Sep 12 06:46:30 CDT 2024]
Issuer: CN=KallahanHome
SerialNumber: [ 5b2c8d37 8fba422c 8ca6b2f8 d4e1c547]
Certificate Extensions: 5
[1]: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: E1 9F 9B E2 58 94 48 39 34 92 B2 AD 4C 9C 5E BC ....X.H94...L.^.
0010: 26 51 EE FD &Q..
]
]
[2]: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:false
PathLen: undefined
]
[3]: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
codeSigning
]
[4]: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
DigitalSignature
Key_Encipherment
]
[5]: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E1 9F 9B E2 58 94 48 39 34 92 B2 AD 4C 9C 5E BC ....X.H94...L.^.
0010: 26 51 EE FD &Q..
]
]
]
Algorithm: [SHA256withRSA]
Signature:
0000: 40 0F 64 11 67 FD 37 4B 67 36 A2 D6 5B BE DB 95 @.d.g.7Kg6..[...
0010: 4A C4 6B 08 3D 17 69 7A B5 78 4D 03 8D E1 1F 00 J.k.=.iz.xM.....
0020: 8E 5F AE E5 50 C5 8B 05 85 46 62 B1 83 93 76 04 ._..P....Fb...v.
0030: 4C 43 08 A8 F9 49 D4 CD 34 57 D3 DF 90 07 3F 82 LC...I..4W....?.
0040: 26 7C 2F 10 5C 29 EF 4F 19 21 EC 0F B5 8C 2B F9 &./.\).O.!....+.
0050: 8A D5 82 BC 13 A4 D4 27 6D 5D 38 9F BA E3 3D 9A .......'m]8...=.
0060: DA EE 58 64 CC B3 3B 18 61 07 4A 86 AC E3 2C 7C ..Xd..;.a.J...,.
0070: FB 63 C2 BD 98 E1 B0 FF 60 0C 40 1B 8C 44 0A A1 .c......`.@..D..
0080: FF 9D 92 0A A4 57 39 57 FA EC 7F 02 A7 73 F6 D2 .....W9W.....s..
0090: 18 B6 7D FF BC 9E C8 DB 0F 2D 33 94 D4 DC 20 1E .........-3... .
00A0: 22 FB E1 44 D7 49 70 48 14 F0 B0 5B 23 0C 2B 66 "..D.IpH...[#.+f
00B0: 86 4F 3F E1 90 E4 5B C1 3E BE 58 75 40 7D 31 A3 .O?...[.>.Xu@.1.
00C0: F6 BD AD C8 DB 09 F4 55 80 D7 C6 0A 14 36 1A A5 .......U.....6..
00D0: 6B F8 28 AD 08 81 DA C8 00 59 36 F7 A4 7D 5F 76 k.(......Y6..._v
00E0: C8 96 0F 1A 55 81 7D 47 61 5F 32 E0 00 AB 32 A0 ....U..Ga_2...2.
00F0: 08 7C 21 DD CE 16 F0 E8 58 E9 61 9C F9 B2 55 D6 ..!.....X.a...U.
0100: F4 6B 77 B4 FE 87 54 7B EB 14 22 E7 DE A8 32 59 .kw...T..."...2Y
0110: D9 35 14 39 12 6F 01 1A CA 86 3D A6 A2 53 99 E9 .5.9.o....=..S..
0120: A8 09 EF A3 A9 DD 1B B9 0C A3 34 24 6B 1B 85 BA ..........4$k...
0130: A1 42 F7 5D E2 CD 44 58 EF 2F B5 9D FC C5 B5 0A .B.]..DX./......
0140: FE 38 BC FA 00 A2 9B BB 0A 8A 65 2F F1 42 0F C8 .8........e/.B..
0150: 58 58 55 B8 73 AC B6 77 23 82 80 D1 B4 D4 15 1F XXU.s..w#.......
0160: 25 B6 06 C7 93 E0 39 CB E9 B6 34 90 85 21 12 78 %.....9...4..!.x
0170: 48 A2 24 6F 8F 5A A0 BF 66 7C BA E2 F9 ED 23 3A H.$o.Z..f.....#:
0180: 4E BB 5A 71 5D 6F 8B 0D 27 A1 74 EF E3 32 3D E2 N.Zq]o..'.t..2=.
0190: A5 86 92 22 DD 9B 0F A1 92 5C 5F D2 63 80 82 94 ...".....\_.c...
01A0: 66 C1 8C 15 75 65 62 B6 FF 39 8C 35 BB 32 F4 EB f...ueb..9.5.2..
01B0: 07 B4 17 3C 94 E8 DE 46 D8 B8 6A 77 53 4E 7E 90 ...<...F..jwSN..
01C0: 8C DB 0D 42 B7 6E 26 83 B8 A3 B2 44 FB 0C 11 18 ...B.n&....D....
01D0: 4C BA 69 9F 8C 95 94 D8 11 1C 13 C5 ED 02 61 4A L.i...........aJ
01E0: 0F 71 9F 04 41 DD E1 C6 32 3C 4B 92 95 4C 70 94 .q..A...2<K..Lp.
01F0: EA 3E 3E 2D B1 5A EC B1 EA 04 7A 2F FC 45 3F F3 .>>-.Z....z/.E?.
]
jar: Signature File: Manifest digest SHA-256
jar: sigfile 6c50256d1ce5cca5d53c7b3d0bac0adc86a76b97d3b20fefc4a1e17b88da3c19
jar: computed 6c50256d1ce5cca5d53c7b3d0bac0adc86a76b97d3b20fefc4a1e17b88da3c19
jar:
jar: PermittedAlgs mapping:
jar: SHA512withRSA : true
jar: SHA-256 : true
jar: SHA-512 : true
jar: processSignature signed name = HelloWorld.class
jar: done with meta!
jar: beginEntry META-INF/HOMESELF.RSA
>>> Signer
X.509, CN=KallahanHome
[trusted certificate]
jar signed.
Warning:
The signer's certificate is self-signed.
Thanks @hounster for the update.
Hey @saragluna, thanks for the updated repository.
I just gave it another try - and now jarsigner is able to verify the signature:
PS C:\test> jarsigner -verify -debug -verbose -certs -J'-Djava.security.debug=jar' signed-jar.jar
s = signature was verified
m = entry is listed in manifest
k = at least one certificate was found in keystore
- Signed by "CN=Company, OU=Company, O=Company, L=City, C=Country"
Digest algorithm: SHA-384
Signature algorithm: SHA512withRSA, 3072-bit key
jar verified.
Warning:
This jar contains entries whose certificate chain is invalid. Reason: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
This jar contains signatures that do not include a timestamp. Without a timestamp, users may not be able to validate this jar after any of the signer certificates expire (as early as 2025-06-12).
POSIX file permission and/or symlink attributes detected. These attributes are ignored when signing and are not protected by the signature.
The signer certificate will expire on 2025-06-12.
But it throws another issue:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:388)
at java.base/sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:271)
at java.base/sun.security.validator.Validator.validate(Validator.java:256)
at java.base/sun.security.validator.Validator.validate(Validator.java:223)
at jdk.jartool/sun.security.tools.jarsigner.Main.validateCertChain(Main.java:2521)
at jdk.jartool/sun.security.tools.jarsigner.Main.certsAndTSInfo(Main.java:2160)
at jdk.jartool/sun.security.tools.jarsigner.Main.signerInfo(Main.java:2116)
at jdk.jartool/sun.security.tools.jarsigner.Main.verifyJar(Main.java:888)
at jdk.jartool/sun.security.tools.jarsigner.Main.run(Main.java:303)
at jdk.jartool/sun.security.tools.jarsigner.Main.main(Main.java:138)
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at java.base/sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
at java.base/sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
at java.base/java.security.cert.CertPathBuilder.build(CertPathBuilder.java:297)
at java.base/sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:383)
... 9 more
s 4748 Wed Sep 13 08:13:42 GMT+02:00 2023 META-INF/MANIFEST.MF
I am not sure if that is an issue with our certificate, our setup or something else.
I am not sure whether this exception is because the certificate is a self-signed certificate.
Hey @saragluna, we are not using a self-signed certificate - it is an official certificate bought from DigiCert.
@malmor - You can fix the missing timestamp issue by adding this option to your jarsigner command:
-tsa 'http://timestamp.digicert.com'
As to the issue of "certificate chain invalid", don't quote me on this but I believe jarsigner always expects the full certificate chain to be available. Seeing this makes me think that when you followed the steps to "merge" and complete your certificate in Azure Keyvault, that you merged the public certificate only, as opposed to merging a .p7b file containing all of the certificates. One way to confirm is concatenate all of the certificates into a text file, in the proper order, have it locally available on your workstation, and point to it by adding this option to jarsigner:
-certchain INSERT_NAME_OF_FILE_HERE
@malmor Just to clarify in case not clear - when I referred to "all of the certificates", I simply meant all of the public certificates that make up the full chain:
Add them into your "chain file", in that order.
@saragluna @backwind1233
Thanks so much for the latest changes.
The build compiled from the test repo seems to be working okay to me now. I am able to properly sign my jar files and validate them. Do we have any idea when this fix will be officially released in a new version of the JCA provider?
We're trying to understand if this beta version is stable enough for the production environment or it's better to wait for the official version, if it's not too far away from being released. Thanks.
@hounster thanks for the information!
We are already using timestamps when signing our releases - must have missed it when testing the beta version locally. I will play around with the "full chain" issue - if your hint goes in the right direction, then this should be quite easy to test and fix š
Hi @jyuenatsolarsoft, if everything goes well, we could release a new version by the end of this month.
Hi,
is everything working as expected, I am able to sign but not verify and while signing I see this issue "**jar: processEntry caught: java.security.SignatureException: ".
jar: processEntry: processing block jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: jar: Detected signature timestamp (#67777975150123403729185685483830998061) generated on Mon Oct 02 09:31:01 CDT 2023 jar: jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 0 but was expecting 512 jar: done with meta! jar: nothing to verify! jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47
Do you guys have any inputs?
@backwind1233 any assistance?
@schannaveera1 could you provide the certificate advanced policy configuration?
@saragluna, The parameters are as below.
Extended Key Usages : 1.3.6.1.5.5.7.3.1, 1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.3 X.509 key Usage Flags: Digital signature, key encipherment Resurge key on renewal: No Exportable Private Key : No Key Type: RSA HSM Key Size : 4096 Enable certificate Transparency : Yes
FYI. I was getting the same error described, private key is not a DSA or RSA key, in this thread using AzureKeyVault with Entrust. I'm able to confirm that the fork here https://github.com/saragluna/azure-security-kv-jca-fork doesn't throw the error and does result in a successful signing.
We're working through the "PKIX path building failed" issue now, which I believe is due to us missing intermediate certs defined in the AzureKeyVault (or it could be an issue in the KeyVaultJcaProvider).
We're moving from Sectigo SafeNet HSM to Azure Key Vault and when we had this issue with it was because we didn't have the intermediates installed in the HSM so Java didn't know how to find/include the intermediates as part of the signed.
Update: We checked and the full chain is in fact already in the KeyVault, but we do get the PKIX path error. If I take the same chain and pass it in using the -certchain option then it works as expected. So I suspect that the KeyVaultProvider isn't making the chain available... maybe
@brianandle the fix from the fork repo has already been merged, and we will look into the cert chain issue now. But have you tried this https://github.com/Azure/azure-sdk-for-java/issues/35677#issuecomment-1717593203?
Hi,
is everything working as expected, I am able to sign but not verify and while signing I see this issue "**jar: processEntry caught: java.security.SignatureException: ".
jar: processEntry: processing block jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: jar: Detected signature timestamp (#67777975150123403729185685483830998061) generated on Mon Oct 02 09:31:01 CDT 2023 jar: jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 0 but was expecting 512 jar: done with meta! jar: nothing to verify! jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47
Do you guys have any inputs?
@schannaveera1 seems like it's not signed correctly in your case?
@saragluna, In my case I get the error with the message "jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: jar: Detected signature timestamp (#67777975150123403729185685483830998061) generated on Mon Oct 02 09:31:01 CDT 2023 jar: jar: processEntry caught: java.security.SignatureException: Signature length not correct: got 0 but was expecting 512 jar: done with meta! jar: nothing to verify! jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47 jar: Unsupported signer attribute: 1.2.840.113549.1.9.16.2.47
And Jar signed.
For Verify,
WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar).
35677 (comment)
We verified that the full chain exists in the AKV/HSM for the cert, however we still had to define the -certchain=local_cert_chain.pem
which we didn't have to do with Sectigo. So we have a workaround but ideally we wouldn't need to have to define the -certchain
at all as we didn't need yo do that with another vendor.
@saragluna do you need any additional information from to help us resolve.
@schannaveera1, yes, we can't reproduce this error. Could you help provide more information?
Hey everyone, I just wanted to give you a quick update from my side.
@malmor - You can fix the missing timestamp issue by adding this option to your jarsigner command: -tsa 'http://timestamp.digicert.com'
As to the issue of "certificate chain invalid", don't quote me on this but I believe jarsigner always expects the full certificate chain to be available. Seeing this makes me think that when you followed the steps to "merge" and complete your certificate in Azure Keyvault, that you merged the public certificate only, as opposed to merging a .p7b file containing all of the certificates. One way to confirm is concatenate all of the certificates into a text file, in the proper order, have it locally available on your workstation, and point to it by adding this option to jarsigner: -certchain INSERT_NAME_OF_FILE_HERE
Thanks a lot @hounster for your tips regarding the jarsigner warnings. I enabled timestamping and provided the combined list of public keys as a chain.p7b
file - and now jarsigner successfully signs and verifies jars with our certificate stored in a HSM azure key vault š„³
We are now using the latest version v2.8.0 of the azure-security-keyvault-jca jar that contains the support for HSM secrets (FYI @jyuenatsolarsoft).
Here is the command that we are using (windows powershell):
# Sign the jar
# - '-certchain' is required because our certificate in azure is missing the official public certificates in the chain
# - secrets are provided by environment variables
# - we had to hardcode the path to the azure-security-keyvault-jca jar because of some internal limitation
jarsigner ^
-verbose ^
-certchain chain.p7b ^
-keystore NONE ^
-storetype AzureKeyVault ^
-storepass ' ' ^
-tsa http://timestamp.digicert.com ^
target\azure-sdk-for-java-signing-example-1.0.0.jar ^
"$env:AZURE_KEY_VAULT_CERT_NAME" ^
-providerName AzureKeyVault ^
-providerPath C:\repository\com\azure\azure-security-keyvault-jca\2.8.0\azure-security-keyvault-jca-2.8.0.jar ^
-providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider ^
-J"-Dazure.keyvault.uri=$env:AZURE_KEY_VAULT_URL" ^
-J"-Dazure.keyvault.tenant-id=$env:AZURE_KEY_VAULT_TENANT_ID" ^
-J"-Dazure.keyvault.client-id=$env:AZURE_KEY_VAULT_CLIENT_ID" ^
-J"-Dazure.keyvault.client-secret=$env:AZURE_KEY_VAULT_CLIENT_SECRET"
# Verify the jar
jarsigner -verify -debug -verbose -certs target\azure-sdk-for-java-signing-example-1.0.0.jar`
Thanks a lot @backwind1233 and @saragluna for your support on this issue. š
As far as I am concerned this issue is resolved. But because of the latest questions I will leave it up to you to close this - feel free to keep the conversation going or to move it to a different issue š
Regards, Malte
Hi @saragluna,
I am attaching logs here, there is new error with "azure-security-keyvault-jca-2.8.0.jar. I am not at all able to sign now. Attached are the logs. Any help
The command I am using to sign
"C:\Program Files\Java\jdk-19\bin\jarsigner.exe" -verbose -debug -keystore NONE ^ -sigalg RSASSA-PSS -storetype AzureKeyVault -tsa http://timestamp.digicert.com ^ -storepass " " ^ -providerPath "C:\codesign\jarsign\azure-security-keyvault-jca-2.8.0.jar" ^ -providerName AzureKeyVault -providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider -J-Dazure.keyvault.uri=https://sapguixrx.vault.azure.net/ ^ -J-Dazure.keyvault.client-secret=########^ -J-Dazure.keyvault.client-id=############# ^ -J-Dazure.keyvault.tenant-id=############ ^ -certchain C:\codesign\jarsign\sap.p7b "C:\codesign\jarsign\sample.jar" sapguixrx
"java.lang.SecurityException: invalid SHA-256 signature file digest for com/azure/security/keyvault/jca/implementation/shaded/com/fasterxml/jackson/annotation/JsonProperty$Access.class at java.base/sun.security.util.SignatureFileVerifier.verifySection(SignatureFileVerifier.java:692) at java.base/sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:351) at java.base/sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:282) at java.base/java.util.jar.JarVerifier.processEntry(JarVerifier.java:327) at java.base/java.util.jar.JarVerifier.update(JarVerifier.java:239) at java.base/java.util.jar.JarFile.initializeVerifier(JarFile.java:760) at java.base/java.util.jar.JarFile.getInputStream(JarFile.java:846) at jdk.jartool/sun.security.tools.jarsigner.Main.signJar(Main.java:2032) at jdk.jartool/sun.security.tools.jarsigner.Main.run(Main.java:308) at jdk.jartool/sun.security.tools.jarsigner.Main.main(Main.java:138) jar signed."
@schannaveera1 sorry for the late reply, but on our end we can't reproduce your error. But could you help generate a self-signed certificate in kv, and test whether the library can use that cert to sign the jar? If so, we could narrow the issue to something special in your cert.
Did this fix ultimately get merged?
@karla-barraza are you referring to the jarsigner support (the initial issue described above)?
Then yes, it should be available for all versions starting with v2.8.0 of the azure-security-keyvault-jca
package.
Query/Question Is there a way to integrate the
KeyVaultJcaProvider
withjarsigner
to sign jar files while the private key is stored safely and non-exportable in Azure Key Vault?Because of the new requirement that code signing certificates must be stored on a compliant HSM storage we looked at Azure Key Vault. For most of our artifacts we found working integrations with different tools - but not for jar files.
Based on #22105 the AzureKeyVault provider should be able to work with non-exportable keys - but I did not manage to get this working in
jarsigner
.My commands looks like this:
Can you please advise whether this use case can actually work? This questions somehow aligns with #30659 - because I was not able to find any documentation about this. If it is possible I will gladly create a PR to add an example to the docs!
Why is this not a Bug or a feature Request? As far as I can tell #22105 added support for working with non-exportable keys - so this is not so much about adding a feature but understanding how to configure/implement it.
Setup (please complete the following information if applicable):
mcr.microsoft.com/dotnet/sdk:6.0-windowsservercore-ltsc2019
)Library/Libraries: com.azure:azure-security-keyvault-jca:2.7.1
Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report