如何使用存储在 Azure Key Vault 中且包含信任链的证书正确地进行代码签名?

问题描述 投票:0回答:1

我们的 CA GlobalSign 已颁发适用于 HSM 的代码签名证书。我在 Azure 中创建了高级许可的 Key Vault,因为基本版不支持 HSM。然后,我使用以下颁发策略在 Key Vault 中生成了一个证书:

  • 证书颁发机构 (CA) 类型: 由某个机构颁发的证书 非集成 CA
  • 主题:C=US、L=Doeville、O=JohnDoe、CN=JohnDoe、 [电子邮件受保护]
  • DNS 名称:0 个 DNS 名称
  • 有效期(月):24
  • 内容类型:PKCS#12
  • 启用:

高级策略配置

  • 扩展密钥用法 (EKU):1.3.6.1.5.5.7.3.3
  • X.509 密钥使用标志:数字签名、密钥加密
  • 续订时重复使用密钥?:
  • 可导出私钥?:
  • 密钥类型:RSA-HSM
  • 密钥大小:4096
  • 启用证书透明度?:
  • 证书类型:{空}

在密钥保管库中实例化后,我单击“证书操作”并下载 CSR。

我按照 Global Sign 提供的下载链接复制并粘贴了 CSR。证书生成后,我得到了一个可以下载数字证书和 2 个中间证书的页面。文件名是:OS123456789.cer、intermediate1.cer 和 middle2.cer

然后我返回到 Azure Key Vault 并单击“合并签名请求”,然后选择 OS123456789.cer 文件,并且成功了。

然后我开始使用 jarsigner 来签署我的 jar。 我下载了 azure-security-keyvault-jca-2.8.1.jar 并将其放在 %JAVA_HOME&/jre/lib/ext

我使用的jarsigner命令是这样的:

jarsigner -keystore NONE  -storetype AzureKeyVault -verbose  -storepass "" -tsa http://timestamp.globalsign.com/tsa/r6advanced1 -providerName AzureKeyVault -providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider -J"-Dazure.keyvault.uri=$KEYVAULT_URL" -J"-Dazure.keyvault.tenant-id=$TENANT" -J"-Dazure.keyvault.client-id=$CLIENT_ID" -J"-Dazure.keyvault.client-secret=$CLIENT_SECRET" -signedjar "signed.jar" "unsigned.jar" $CERT_ALIAS

签名输出如下所示:

updating: META-INF/MANIFEST.MF
adding: META-INF/GLOBALSI.SF
requesting a signature timestamp
TSA location: http://timestamp.globalsign.com/tsa/r6advanced1
adding: META-INF/GLOBALSI.RSA
A BUNCH OF FILES
signing: clientlogging.properties
adding: JNLP-INF/
signing: JNLP-INF/APPLICATION_TEMPLATE.JNLP
>>> Signer
X.509, [email protected], CN=JohnDoe, O=JohnDoe, L=DoeVille, C=US
[trusted certificate]
>>> TSA
X.509, CN=Globalsign TSA for CodeSign1 - R6 - 202311, O=GlobalSign nv-sa, C=BE
[certificate is valid from 07/11/23 18:13 to 09/12/34 18:13]
X.509, CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE
[certificate is valid from 20/06/18 02:00 to 10/12/34 01:00]
X.509, CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6
[trusted certificate]

jar signed.

The timestamp will expire on 2034-12-09.

我认为到目前为止看起来不错。 然而,当我跑步时:

jarsigner -verify -verbose -certs signed.jar

我得到以下输出:

s 291951 Tue Sep 24 12:09:10 CEST 2024 META-INF/MANIFEST.MF

>>> Signer
X.509, [email protected], CN=JohnDoe, O=JohnDoe, L=DoeVille, C=US
[certificate is valid from 20/09/24 16:00 to 03/09/27 14:19]
[Invalid certificate chain: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
>>> TSA
X.509, CN=Globalsign TSA for CodeSign1 - R6 - 202311, O=GlobalSign nv-sa, C=BE
[certificate is valid from 07/11/23 18:13 to 09/12/34 18:13]
X.509, CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE
[certificate is valid from 20/06/18 02:00 to 10/12/34 01:00]
X.509, CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6
[trusted certificate]

292002 Tue Sep 24 12:09:12 CEST 2024 META-INF/GLOBALSI.SF
8401 Tue Sep 24 12:09:12 CEST 2024 META-INF/GLOBALSI.RSA
0 Tue Sep 10 16:47:38 CEST 2024 META-INF/
    
A BUNCH OF FILES

sm 1111 Tue Sep 10 16:47:36 CEST 2024 JNLP-INF/APPLICATION_TEMPLATE.JNLP
[entry was signed on 24/09/24 12:09]
>>> Signer
X.509, [email protected], CN=JohnDoe, O=JohnDoe, L=DoeVille, C=US
[certificate is valid from 20/09/24 16:00 to 03/09/27 14:19]
[Invalid certificate chain: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target]
>>> TSA
X.509, CN=Globalsign TSA for CodeSign1 - R6 - 202311, O=GlobalSign nv-sa, C=BE
[certificate is valid from 07/11/23 18:13 to 09/12/34 18:13]
X.509, CN=GlobalSign Timestamping CA - SHA384 - G4, O=GlobalSign nv-sa, C=BE
[certificate is valid from 20/06/18 02:00 to 10/12/34 01:00]
X.509, CN=GlobalSign, O=GlobalSign, OU=GlobalSign Root CA - R6
[trusted certificate]

s = signature was verified 
m = entry is listed in manifest
k = at least one certificate was found in keystore
i = at least one certificate was found in identity scope

Signed by "[email protected], CN=JohnDoe, O=JohnDoe, L=DoeVille, C=US"
Digest algorithm: SHA-256
Signature algorithm: SHA256withRSA, 4096-bit key
Timestamped by "CN=Globalsign TSA for CodeSign1 - R6 - 202311, O=GlobalSign nv-sa, C=BE" on Tue Sep 24 10:09:12 UTC 2024
Timestamp digest algorithm: SHA-256
Timestamp signature algorithm: SHA256withSHA256withRSA, 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

The signer certificate will expire on 2027-09-03.
The timestamp will expire on 2034-12-09.

验证失败并出现以下警告:

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

据我了解,发生这种情况是因为它无法确定 CA 的信任链。 然后,我使用 keytool 将中间证书导入到位于我的主目录下的本地密钥库中。然后我再次对 jar 文件进行签名,这次 jarsigner 能够验证 jar 文件而不会出现任何警告。

但是,当我部署 java 应用程序并且用户下载 jnlp 文件并尝试安装 java 应用程序时,他们会收到一个警告弹出窗口,指出签名的应用程序不受信任。

我们正在使用 java 8。尝试了最新的 Amazon Corretto 和 Oracles

我的问题是:

  1. 您对如何解决这个问题有什么想法吗?
  2. 合并签名请求时是否可以包含中间证书,这会解决问题吗?

感谢您提供的任何帮助。

java azure-keyvault keystore code-signing code-signing-certificate
1个回答
0
投票

我能够弄清楚。 您需要通过 -certchain 选项将证书信任链作为 pem 文件提供给 jarsigner。 这是正确的命令:

jarsigner -certchain trustchain.pem -keystore NONE  -storetype AzureKeyVault -verbose  -storepass "" -tsa http://timestamp.globalsign.com/tsa/r6advanced1 -providerName AzureKeyVault -providerClass com.azure.security.keyvault.jca.KeyVaultJcaProvider -J"-Dazure.keyvault.uri=$KEYVAULT_URL" -J"-Dazure.keyvault.tenant-id=$TENANT" -J"-Dazure.keyvault.client-id=$CLIENT_ID" -J"-Dazure.keyvault.client-secret=$CLIENT_SECRET" -signedjar "signed.jar" "unsigned.jar" $CERT_ALIAS

要创建 pem 文件,您需要将代码签名证书与中间证书连接起来。顺序很重要:

cat codesigner.cer, intermediate1.cer, intermediate.cer > bundle.pem

您还可以使用文本编辑器来组合证书。

当您使用 -verbose 选项运行 jarsigner 并查看完整的信任链时,您就会知道它是有效的:

>>> Signer
X.509, [email protected], CN=JohnDoe, O=JohnDoe, L=DoeVille, C=US
[certificate is valid from 20/09/24 16:00 to 03/09/27 14:19] 
X.509, CN=GlobalSign Code Signing Root R45, O=GlobalSign nv-sa, C=BE
[trusted certificate]
X.509, CN=GlobalSign GCC R45 CodeSigning CA 2020, O=GlobalSign nv-sa, C=BE
[trusted certificate]
© www.soinside.com 2019 - 2024. All rights reserved.