Closed gillg closed 3 years ago
Anyone could confirm if this approach is possible ?
If there is a java.security.KeyStore implementation wrapping the Azure KeyVault service (or a PKCS#11 interface) that would be trivial to integrate it with Jsign.
The Azure SDK has a JCA provider: https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/keyvault/azure-security-keyvault-jca
The Azure SDK has a JCA provider: https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/keyvault/azure-security-keyvault-jca
Good to know ! Their example only use it to fetch certificate and key. In the signing scenario (with an EV cert for example), your key is defined as not exportable, so you can never know it. Maybe they also suppurt virtualy signing using jca API.
Anyone could try to implement something ? I can help for tests and the approach, but my java knowledge doesn't permit to do it by myself.
The Azure JCA provider is missing a Signature service, it looks like it is insufficient for signing files.
Great !! 🎉
@gillg Could you give it a try? I hope I got it right.
Yes definitely ! Maybe not today, but I keep you in touch. Could you just give me a valid jar release ?
You can generate one with "mvn package -DskipTests", the jar to use is in jsign/target/jsign/jsign-4.0-SNAPSHOT.jar
Hello @ebourg !
I can test it and it seems almost working 👍
Calls to Azure seems OK
java -jar .\jsign-4.0-SNAPSHOT.jar `
--storetype AZUREKEYVAULT `
--keystore "$Vault" `
--alias "$Certif" `
--tsaurl "http://rfc3161timestamp.globalsign.com/advanced" `
--tsmode RFC3161 `
--alg SHA-256 `
--storepass "$(az account get-access-token --resource "https://vault.azure.net" --tenant $Tenant | ConvertFrom-Json | Select-Object -ExpandProperty accessToken)" `
--name "xxxxxxxxx" `
--url "https://www.xxxxxxxx.com" `
'.\Downloads\xxxxxxxxxxxxxxxxxx-v1.3.exe'
Adding Authenticode signature to .\Downloads\xxxxxxxxxxxxxxxx-v1.3.exe
jsign: Couldn't sign .\Downloads\xxxxxxxxxxxxxxxxxxxxxx-v1.3.exe
java.lang.IllegalArgumentException: Unknown signature type requested: SHA256WITHRSA-HSM
at net.jsign.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder.generate(Unknown Source)
at net.jsign.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder.find(Unknown Source)
at net.jsign.bouncycastle.operator.jcajce.JcaContentSignerBuilder.<init>(Unknown Source)
at net.jsign.AuthenticodeSigner.createSignedDataGenerator(AuthenticodeSigner.java:403)
at net.jsign.AuthenticodeSigner.createSignedData(AuthenticodeSigner.java:366)
at net.jsign.AuthenticodeSigner.sign(AuthenticodeSigner.java:338)
at net.jsign.SignerHelper.sign(SignerHelper.java:474)
at net.jsign.JsignCLI.execute(JsignCLI.java:113)
at net.jsign.JsignCLI.main(JsignCLI.java:40)
I don't know how, but maybe just map "SHA256WITHRSA-HSM" to "SHA256WITHRSA" should work. In fact it's just the same thing hosted in an HSM hardware... 🤞
One other remark, I'm not sure it's a good idea to hardcode .vault.azure.net
in --keystore. I'm not sure it can change but in official tools you have to provide it, and microsoft is pretty fan of "on-premise" solutions with custom tenants and URLs.
Could you try again with this change please?
--- a/jsign-core/src/main/java/net/jsign/jca/AzureKeyVaultSigningService.java
+++ b/jsign-core/src/main/java/net/jsign/jca/AzureKeyVaultSigningService.java
@@ -126,7 +126,7 @@ public class AzureKeyVaultSigningService implements SigningService {
String kid = (String) response.get("kid");
Map policy = (Map) response.get("policy");
Map keyprops = (Map) policy.get("key_props");
- String algorithm = (String) keyprops.get("kty");
+ String algorithm = ((String) keyprops.get("kty")).replace("-HSM", "");
return new SigningServicePrivateKey(kid, algorithm);
} catch (AzureException | IOException e) {
Regarding the vault name you are probably right. I think I'll add support for an URL in addition to the short form.
Could you push it in one of your branch 🙏 ? It's a pretty complex to test it, I don't have a java dev env localy, so I build it on a build server and I can't change code online...
You can try with the azure
branch
Perfect ! No errors during the process. You can merge it if you want :)
But I have another issue now... I will create another issue to avoid mixing problems.
Great! That's merged now. Many thanks for your help.
A
storetype
AZURE_KEYVAULT could be great ! For information storing a certificate on Azure KeyVault is almost free and is compliant to store an EV cert.The need is to implement a simple API call to https://docs.microsoft.com/en-us/rest/api/keyvault/sign/sign with https://github.com/Azure/azure-sdk-for-java
In this case the user needs to provide new args to the cli :
--azure-key-vault-url
(can be targeted to the existing--keystore
arg)--azure-key-vault-certificate
(can be targeted to the existing--alias
arg)--azure-key-vault-accesstoken
(can be targeted to the existing--password
arg) this parameter is mandatory for autentication. The user already has one or can generate it on the fly withaz account get-access-token --resource "https://vault.azure.net" --tenant $tenantID
for example.Optional args for auth : These 3 args can be used to call the similar call
az account get-access-token ....
through the SDK.--azure-key-vault-accesstoken
can be ignored in this case.To store the cert used in the JAR you just need to use : https://docs.microsoft.com/en-us/rest/api/keyvault/getcertificate/getcertificate Get the cert also permits to get its associated "key-id" and "key-version" used to call the sign method.
The API method https://docs.microsoft.com/en-us/rest/api/keyvault/sign/sign wait for a body like
{"alg":"RS256","body":"data-digest-to-sign"}
and return the signature in base64. The alg can be one of https://docs.microsoft.com/en-us/rest/api/keyvault/sign/sign#jsonwebkeysignaturealgorithmJAVA needs to sign : https://azuresdkdocs.blob.core.windows.net/$web/java/azure-security-keyvault-keys/4.2.8/com/azure/security/keyvault/keys/cryptography/CryptographyClient.html#sign-com.azure.security.keyvault.keys.cryptography.models.SignatureAlgorithm-byte:A- JAVA needs to fetch the cert used : https://azuresdkdocs.blob.core.windows.net/$web/java/azure-security-keyvault-certificates/4.1.8/com/azure/security/keyvault/certificates/CertificateClient.html#getCertificate-java.lang.String-