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
Describe the bug
I have an issue using signing jars with the
com.azure.security.keyvault.jca.KeyVaultJcaProviderprovider using a certificate with a non-exportable keyException or Stack Trace
Using the jarsigner cli tool I get the following error
From the coded solution
To Reproduce
Following the steps documented in https://github.com/backwind1233/AzureDocs/blob/main/AzureJavaSDK/JCA/integrate_keyvault_JCA_provider_with_jarsigner.md
I'm using the
SHA256withRSAsignature algorithmSee 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
KeyVaultPrivateKeyis not a supported key type. The methodsupportsKeyClassinside thejava.security.Providermodule of the JDK expects keys to implement one of the following interfacesinterface java.security.interfaces.RSAPrivateKey
interface java.security.interfaces.RSAPublicKey
Code Snippet
Test code
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):
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