因此,作为参考,这是我正在做的工作:
对存储在证书刀片中的 .pkcs12 的调用有效:
CertificateClient certificateClient = new CertificateClientBuilder()
.vaultUrl(System.getenv("AzureWebJobsSecretStorageKeyVaultUri"))
.credential(clientSecretCredential)
.buildClient();
KeyVaultCertificateWithPolicy certificate = certificateClient
.getCertificate(certificateAzureName);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream inputStream = new ByteArrayInputStream(certificate
.getCer());
X509Certificate x509Certificate = (X509Certificate) certFactory
.generateCertificate(inputStream);
keyStore.setCertificateEntry(nonprodCertificateAlias, x509Certificate);
此外,调用获取公共证书链,将其存储为秘密(与上面类似,但没有私钥)。这有效:
SecretClient secretClient = new SecretClientBuilder()
.vaultUrl(envUtil.getProperty(AppVar.AzureWebJobsSecretStorageKeyVaultUri))
.credential(clientSecretCredential)
.buildClient();
log.info("Created SecretClient.");
Objects.requireNonNull(secretClient, "Azure SecretClient is null. Could not
be constructed.");
KeyVaultSecret secret = secretClient.getSecret(publicChainAzureName);
String encodedString = secret.getValue();
byte[] decodedCertChain = Base64.getDecoder().decode(encodedString);
....
Certificate certificate1 = certFactory
.generateCertificate(new ByteArrayInputStream(decodedCertChain));
keyStore.setCertificateEntry(nonprodCertificateAlias, certificate1);
但是,我无法下载私钥(
pkcs8
pem 格式和 RSA)来工作。这是只给我错误的代码Method threw 'java.security.spec.InvalidKeySpecException' exception: Invalid key format
:
Certificate publicKeyChainCert = certFactory.generateCertificate(new ByteArrayInputStream(decodedCertChainSecret));
//keyStore.setCertificateEntry(pubCertChainAlias, publicKeyChainCert);
KeyVaultSecret secretKey = secretClient.getSecret(privateKeyAzureName);
String encodedPrivateKey = secretKey.getValue();
byte[] decodedPrivateKey = Base64.getDecoder().decode(encodedPrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// next line throws this
// error: Method threw 'java.security.spec.InvalidKeySpecException' exception.
// : Invalid key format
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(decodedPrivateKey);
privateKey = keyFactory.generatePrivate(privateKeySpec);
keystore.setKeyEntry(pkCertAlias, privateKey, null,
new Certificate[]{publicKeyChainCert});
注意:我使用 Keytool Explorer 从 .pfx 密钥库导出 .pkcs8 私钥。我将该秘密上传到我的 KeyVault 的“秘密”刀片中。所以,我认为下载和 Base64 解码应该让我返回完全相同的文件,但看起来却没有?
创建或导入 PEM 文件 (
application/x-pem-file
) 时,秘密值不是 Base64 编码的。它是一个包含 PEM 的原始 ASCII 字符串,使用 \n
表示换行。
我的 Java 很生锈(有些双关语),但你应该能够省略示例中的几行中间线:
Certificate publicKeyChainCert = certFactory.generateCertificate(new ByteArrayInputStream(decodedCertChainSecret));
//keyStore.setCertificateEntry(pubCertChainAlias, publicKeyChainCert);
KeyVaultSecret secretKey = secretClient.getSecret(privateKeyAzureName);
String privateKey = secretKey.getValue();
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKey);
privateKey = keyFactory.generatePrivate(privateKeySpec);
keystore.setKeyEntry(pkCertAlias, privateKey, null,
new Certificate[]{publicKeyChainCert});
这就是我在 Key Vault .NET
CertificateClient
中所做的,它提供了类似的 DownloadCertificateAsync
方法,可以对证书策略内容类型进行 Base64 解码,您可以通过评估证书策略来获取该内容类型,或者应该设置该内容类型在托管机密的 contentType
属性中 - application/x-pem-file
或 application/x-pkcs12
。