使用 Java Azure SDK 从 Azure KeyVault 下载 pkcs8 私钥的技巧是什么?

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

因此,作为参考,这是我正在做的工作:

  1. 对存储在证书刀片中的 .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);
    
  2. 此外,调用获取公共证书链,将其存储为秘密(与上面类似,但没有私钥)。这有效:

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 解码应该让我返回完全相同的文件,但看起来却没有?

java ssl-certificate certificate azure-keyvault azure-sdk
1个回答
0
投票

创建或导入 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

© www.soinside.com 2019 - 2024. All rights reserved.