我从 Azure keyvault 证书在 java 中得到了什么

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

证书在 Azure KeyVault 中创建。我需要从中下载公钥和私钥。

当content type为PEM时,我可以获取到私钥并转换成RSA PrivateKey。

            //when certificate is created with pem format, downloadedPK has both private and certificate sections
            //needs to extract the raw Private Key
            if ("application/x-pem-file".equalsIgnoreCase(privateKeyType)) {
                /*
                -----BEGIN PRIVATE KEY-----
                -----END PRIVATE KEY-----
                -----BEGIN CERTIFICATE-----
                -----END CERTIFICATE-----
                 */

当内容类型是PKCS12时,我不确定它是什么

 //when certificate is created with pkcs12 format, downloadedPK doesn't have any -----BEGIN * KEY-----
 //It's readable format similar to private key/certificate inside .pem file but without any "-----BEGIN *----- "

这是我的代码:

        ClientSecretCredential credential = new ClientSecretCredentialBuilder()
                .tenantId(tenantId)
                .clientId(clientId)
                .clientSecret(clientSecret)
                .build();

        CertificateClient certificateClient = new CertificateClientBuilder()
                .vaultUrl(vaultUri)
                .credential(credential)
                .buildClient();

        SecretClient secretClient = new SecretClientBuilder()
                .vaultUrl(vaultUri)
                .credential(credential)
                .buildClient();

        // Retrieving certificate
        KeyVaultCertificateWithPolicy certificateWithPolicy = certificateClient.getCertificate(alias);

        // Retrieving secrete for private key
        KeyVaultSecret secret = secretClient.getSecret(alias, certificateWithPolicy.getProperties().getVersion());
        
        String downloadedPK = secret.getValue();
        String privateKeyType = secret.getProperties().getContentType();

        byte[] rawPrivateKey = null;

            //when certificate is created with pem format, downloadedPK has both private and certificate sections
            //needs to extract the raw Private Key
            if ("application/x-pem-file".equalsIgnoreCase(privateKeyType)) {
                /*
                -----BEGIN PRIVATE KEY-----
                -----END PRIVATE KEY-----
                -----BEGIN CERTIFICATE-----
                -----END CERTIFICATE-----
                 */
                int endIndex = downloadedPK.indexOf("-----END PRIVATE KEY-----");
                String str1 = downloadedPK.substring(0, endIndex);

                privateKeyContent = str1.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "");
            }

            //when certificate is created with pkcs12 format, downloadedPK doesn't have any -----BEGIN * KEY-----
            //It's readable format similar to private key/certificate inside .pem file but without any "-----BEGIN *----- "
            if ("application/x-pkcs12".equalsIgnoreCase(privateKeyType)) {

                //downloadedPK is "MIIKOAIBAzCCCfQGCSqGSIb3DQEHA...+1Q1jLj89b50AgIH0A==""
                privateKeyContent = downloadedPK;
            }

            rawPrivateKey = Base64.getDecoder().decode(privateKeyContent);

            KeyFactory kf = KeyFactory.getInstance("RSA");

            PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
            PrivateKey privateRsaKey = kf.generatePrivate(keySpecPKCS8);

我在这里检查了这篇文章的 .NET 上传到 Azure Key Vault 的证书在作为秘密下载时有不同的内容 它可以立即使用 secret.Value 作为 byte[] pfx.

// For PEM, you'll need to extract the base64-encoded message body.
// .NET 5.0 preview introduces the System.Security.Cryptography.PemEncoding class to make this easier.
if ("application/x-pkcs12".Equals(secret.Properties.ContentType, StringComparison.InvariantCultureIgnoreCase))
{
    byte[] pfx = Convert.FromBase64String(secret.Value);
    return new X509Certificate2(pfx);
}

但是我在 java 中下载的 PK 是什么

MIIKOAIBAzCCCfQGCSqGSIb3DQEHA...+1Q1jLj89b50AgIH0A==

我收到了这个错误。这是否意味着我得到了 pkcs12 格式的私钥字符串?我该如何处理这个 pkcs12 字符串?

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : version mismatch: (supported:     00, parsed:     03
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)
    at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390)
java c# .net azure azure-keyvault
1个回答
0
投票

它应该是正确的 P12 密钥库格式(如果您从命令行生成密钥库,则可以使用 Java Keytool 生成相同的格式)。

这应该可以帮助您了解如何将其转换为证书: https://github.com/nagyesta/lowkey-vault/blob/0c3fde5ad7f433d72ded05f6d3e55a3bb55aec18/lowkey-vault-docker/src/test/java/com/github/nagyesta/lowkeyvault/steps/CertificateStepDefAssertion.java#L125-L139

此外,这些行可以帮助显示我在导入过程中如何解析假设相同的东西:https://github.com/nagyesta/lowkey-vault/blob/0c3fde5ad7f433d72ded05f6d3e55a3bb55aec18/lowkey-vault-app/src/main/java /com/github/nagyesta/lowkeyvault/service/certificate/impl/CertContentType.java#L44-L69

当您下载证书存储内容作为秘密时,它应该使用基于此的空白密码:https://learn.microsoft.com/en-us/azure/key-vault/certificates/how-to-export -certificate?tabs=azure-cli#export-stored-certificates(我认为它们的意思是“”中的空白而不是 null,因为 null 在 Java 上会出现问题:Sun Java KeyManagerFactory 和 null passwords

注意:还没有用原始 AKV 尝试此代码,只是我的测试替身,这只是它应该如何工作。

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