[BUG] Error signing jar: Error in signer materials using KeyVaultJcaProvider
Describe the bug
I have an issue using signing jars with the com.azure.security.keyvault.jca.KeyVaultJcaProvider provider using a certificate with a non-exportable key
Exception or Stack Trace Using the jarsigner cli tool I get the following error
jarsigner: unable to sign jar: java.security.InvalidKeyException: No installed provider supports this key: com.azure.security.keyvault.jca.implementation.KeyVaultPrivateKey
From the coded solution
Error signing jar: Error in signer materials
java.lang.RuntimeException: jdk.security.jarsigner.JarSignerException: Error in signer materials
at uk.arqit.support.service.SignerService.signJar(SignerService.kt:28)
at uk.arqit.support.SignerCommand.run(SignerCommand.kt:25)
at picocli.CommandLine.executeUserObject(CommandLine.java:2026)
at picocli.CommandLine.access$1500(CommandLine.java:148)
at picocli.CommandLine$RunLast.executeUserObjectOfLastSubcommandWithSameParent(CommandLine.java:2461)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2453)
at picocli.CommandLine$RunLast.handle(CommandLine.java:2415)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2273)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
at picocli.CommandLine.execute(CommandLine.java:2170)
at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:137)
at io.micronaut.configuration.picocli.PicocliRunner.run(PicocliRunner.java:114)
at uk.arqit.support.SignerCommand$Companion.main(SignerCommand.kt:30)
at uk.arqit.support.SignerCommand.main(SignerCommand.kt)
Caused by: jdk.security.jarsigner.JarSignerException: Error in signer materials
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign(JarSigner.java:564)
at uk.arqit.support.service.SignerService.signJar(SignerService.kt:25)
... 13 more
Caused by: java.security.InvalidKeyException: No installed provider supports this key: com.azure.security.keyvault.jca.implementation.KeyVaultPrivateKey
at java.base/java.security.Signature$Delegate.chooseProvider(Signature.java:1303)
at java.base/java.security.Signature$Delegate.engineInitSign(Signature.java:1388)
at java.base/java.security.Signature.initSign(Signature.java:684)
at java.base/java.security.Signature$1.initSign(Signature.java:147)
at java.base/sun.security.util.SignatureUtil.initSignWithParam(SignatureUtil.java:189)
at java.base/sun.security.util.SignatureUtil.autoInitInternal(SignatureUtil.java:372)
at java.base/sun.security.util.SignatureUtil.fromKey(SignatureUtil.java:364)
at java.base/sun.security.pkcs.PKCS7.generateNewSignedData(PKCS7.java:750)
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign0(JarSigner.java:848)
at jdk.jartool/jdk.security.jarsigner.JarSigner.sign(JarSigner.java:554)
... 14 more
To Reproduce Following the steps documented in https://github.com/backwind1233/AzureDocs/blob/main/AzureJavaSDK/JCA/integrate_keyvault_JCA_provider_with_jarsigner.md
jarsigner -verbose -J-Djava.security.debug=jar \
-keystore NONE \
-storetype AzureKeyVault \
-signedjar appsigned.jar app.jar "redacted" \
-storepass ' ' \
-sigalg SHA256withRSA \
-tsa http://timestamp.entrust.net/rfc3161ts2 \
-providerName AzureKeyVault \
-providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider \
-J--module-path="/home/grant/projects/cosign/azure-security-keyvault-jca-2.8.1.jar" \
-J--add-modules="com.azure.security.keyvault.jca" \
-J-Dazure.keyvault.uri=redacted \
-J-Dazure.keyvault.tenant-id=redacted \
-J-Dazure.keyvault.client-id=redacted \
-J-Dazure.keyvault.client-secret=redacted
I'm using the SHA256withRSA signature algorithm
See the same issue in JDK 17 and 21
I see the same error with the coded solution (snippet below).
Debugging this code, it would appear that the KeyVaultPrivateKey is not a supported key type. The method supportsKeyClass inside the java.security.Provider module of the JDK expects keys to implement one of the following interfaces
interface java.security.interfaces.RSAPrivateKey interface java.security.interfaces.RSAPublicKey
Code Snippet Test code
@Singleton
class SignerService(private val keyVaultClient: KeyVaultClient) : ISignerService {
override fun signJar(alias: String, inputFilePath: String, outputFilePath: String) {
val privateKey = keyVaultClient.getKey(alias, null)
val certificate = keyVaultClient.getCertificate(alias)
val jarSigner = JarSigner.Builder(KeyStore.PrivateKeyEntry(privateKey as PrivateKey, arrayOf(certificate)))
.digestAlgorithm("SHA-256")
.signatureAlgorithm("SHA256withRSA")
.build()
try {
val inZip = ZipFile(inputFilePath)
val outputStream = FileOutputStream(outputFilePath)
jarSigner.sign(inZip, outputStream)
} catch(e: Throwable) {
println("Error signing jar: ${e.message}")
throw RuntimeException(e)
}
}
}
Expected behavior I would expect KeyValutPrivateKey to be recognised as a valid key class and for signing inside the key vault to be actioned.
Screenshots If applicable, add screenshots to help explain your problem.
Setup (please complete the following information):
- OS: Ubuntu 22.04 (WSL)
- IDE: Intellij / bash console
- Library/Libraries: com.azure:azure-security-keyvault-jca:2.8.1
- Java version: Tested with 17 and 21
- App Server/Environment: N/A
- Frameworks: Micronaut in test code
Additional context N/A
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
- [x] Bug Description Added
- [x] Repro Steps Added
- [x] Setup information Added
@chenrujun @moarychan @netyyyy @saragluna
Thank you for your feedback. Tagging and routing to the team member best able to assist.
In addition, the keytype I am testing with in the vault is RSA-HSM. Have re-run CLI and code solution tests again with RSASSA-PSS sign algorithm as per README.md, but am seeing the same outcome.
Hi, We ran into the same problem today. Will this be fixed in the near future? Thanks!
Sorry for the late response.
I use the following code and it sign successfully:
KeyVaultJcaProvider provider = new KeyVaultJcaProvider();
Security.addProvider(provider);
String alias = "signer240727";
PrivateKey privateKey = (PrivateKey) keyVaultClient.getKey(alias, null);
Certificate certificate = keyVaultClient.getCertificate(alias);
JarSigner jarSigner = new JarSigner.Builder(new KeyStore.PrivateKeyEntry(privateKey, new Certificate[]{certificate}))
.digestAlgorithm("SHA-256")
.signatureAlgorithm("SHA256withRSA")
.build();
ZipFile inZip = new ZipFile("C:\\Users\\rujche\\Work\\problem-investigation\\jca\\unsigned.jar");
OutputStream outputStream = new FileOutputStream("C:\\Users\\rujche\\Work\\problem-investigation\\jca\\signedJar.jar");
jarSigner.sign(inZip, outputStream);
With out the following 2 lines, I faced this error: No installed provider supports this key: com.azure.security.keyvault.jca.implementation.KeyVaultPrivateKey.
KeyVaultJcaProvider provider = new KeyVaultJcaProvider();
Security.addProvider(provider);
Hi @rujche,
I am still running into the same Problem. We have an Azure Key Vault with an older certificate + key pair which works completely fine. A few weeks ago we got a new, keyless certificate. This one still works with the AzuerSignTool but not anymore with the jarsigner.
I am using this command: jarsigner -keystore NONE -storetype AzureKeyVault \ -signedjar C:\Users\generic\Desktop\testjar_after.jar C:\Users\generic\Desktop\testjar.jar "REDACTED" \ -verbose -J-Djava.security.debug=jar \ -storepass "" -sigalg SHA256withRSA \ -providerName AzureKeyVault \ -providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider \ -tsa http://timestamp.globalsign.com/tsa/r6advanced1 \ -J--module-path="C:\utl\java\azure-security-keyvault-jca-2.8.1.jar" \ -J--add-modules="com.azure.security.keyvault.jca" \ -J-Dazure.keyvault.uri=REDACTED \ -J-Dazure.keyvault.tenant-id=REDACTED \ -J-Dazure.keyvault.client-id=REDACTED \ -J-Dazure.keyvault.client-secret=REDACTED
Which yields: jarsigner: unable to sign jar: java.security.InvalidKeyException: No installed provider supports this key: com.azure.security.keyvault.jca.implementation.KeyVaultPrivateKey
The Key Type is RSA-HSM, The Key Size is 4096.
Any advice would be greatly appreciated.
As show above, this is a bug which will be fixed by this commit in https://github.com/Azure/azure-sdk-for-java/pull/41303
Hi, @rujche Thanks so much!