Nano Hash - криптовалюты, майнинг, программирование

Сертификат загрузки Azure Key Vault с закрытым ключом

Я пытаюсь загрузить сертификаты, которые у меня есть на нескольких KeyVaults, включая их закрытые ключи. Через портал Azure я могу сделать это без проблем, просто зайдя в KeyVault, выбрав сертификат и нажав Загрузить в формате PFX / PEM.

Поскольку мне нужно повторить одну и ту же операцию с несколькими клавишами, я искал автоматический способ сделать это. Пока я прихожу к следующему:

$objCertificate = (Get-AzKeyVaultCertificate -VaultName <Key Vault> -Name <Certificate Name>).Certificate
$bytCertificate = $objCertificate.Export('pfx',<Password>)
$strCertificate = [System.Convert]::ToBase64String($bytCertificate)
$strPath = Join-Path $env:TEMP "$($objCertificate.Subject).pfx"
$bytCertificate | Set-Content -Path $strPath -Force -Encoding Byte

Проблема в том, что он загружает сертификат только с открытым ключом, и мне также нужен закрытый ключ, включенный в него, так же, как когда я загружаю его через портал. Вы знаете, что я мог упустить?


Ответы:


1

Чтобы получить закрытый ключ, вам нужно получить его в секрете (да, это странно), у меня нет ответа в PowerShell, но я надеюсь, что приведенный ниже код C # может дать вам несколько советов о том, как это сделать.

        /// <summary>
        /// Load a certificate (with private key) from Azure Key Vault
        ///
        /// Getting a certificate with private key is a bit of a pain, but the code below solves it.
        /// 
        /// Get the private key for Key Vault certificate
        /// https://github.com/heaths/azsdk-sample-getcert
        /// 
        /// See also these GitHub issues: 
        /// https://github.com/Azure/azure-sdk-for-net/issues/12742
        /// https://github.com/Azure/azure-sdk-for-net/issues/12083
        /// </summary>
        /// <param name="config"></param>
        /// <param name="certificateName"></param>
        /// <returns></returns>
        public static X509Certificate2 LoadCertificate(IConfiguration config, string certificateName)
        {
            string vaultUrl = config["Vault:Url"] ?? "";
            string clientId = config["Vault:ClientId"] ?? "";
            string tenantId = config["Vault:TenantId"] ?? "";
            string secret = config["Vault:Secret"] ?? "";

            Console.WriteLine($"Loading certificate '{certificateName}' from Azure Key Vault");

            var credentials = new ClientSecretCredential(tenantId: tenantId, clientId: clientId, clientSecret: secret);
            var certClient = new CertificateClient(new Uri(vaultUrl), credentials);
            var secretClient = new SecretClient(new Uri(vaultUrl), credentials);

            var cert = GetCertificateAsync(certClient, secretClient, certificateName);

            Console.WriteLine("Certificate loaded");
            return cert;
        }


        /// <summary>
        /// Helper method to get a certificate
        /// 
        /// Source https://github.com/heaths/azsdk-sample-getcert/blob/master/Program.cs
        /// </summary>
        /// <param name="certificateClient"></param>
        /// <param name="secretClient"></param>
        /// <param name="certificateName"></param>
        /// <returns></returns>
        private static X509Certificate2 GetCertificateAsync(CertificateClient certificateClient,
                                                                SecretClient secretClient,
                                                                string certificateName)
        {

            KeyVaultCertificateWithPolicy certificate = certificateClient.GetCertificate(certificateName);

            // Return a certificate with only the public key if the private key is not exportable.
            if (certificate.Policy?.Exportable != true)
            {
                return new X509Certificate2(certificate.Cer);
            }

            // Parse the secret ID and version to retrieve the private key.
            string[] segments = certificate.SecretId.AbsolutePath.Split('/', StringSplitOptions.RemoveEmptyEntries);
            if (segments.Length != 3)
            {
                throw new InvalidOperationException($"Number of segments is incorrect: {segments.Length}, URI: {certificate.SecretId}");
            }

            string secretName = segments[1];
            string secretVersion = segments[2];

            KeyVaultSecret secret = secretClient.GetSecret(secretName, secretVersion);

            // 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);
            }

            throw new NotSupportedException($"Only PKCS#12 is supported. Found Content-Type: {secret.Properties.ContentType}");
        }
    }
}
01.12.2020
  • Спасибо, определенно помогает. Никогда не подумайте, что закрытый ключ будет храниться в секрете, поскольку он не отображается как таковой на портале Azure. 02.12.2020

  • 2

    Вы должны загрузить сертификат как секрет, а не как сертификат. Из https://azidentity.azurewebsites.net/post/2018/05/17/azure-key-vault-app-service-certificates-finding-downloading-and-converting:

    Connect-AzAccount
    
    $vaultName  = "<NameOfKeyVault>"
    $keyVaultSecretName = "<NameOfTheSecretWhereCertificateIsStored>"
    
    $secret = Get-AzureKeyVaultSecret -VaultName $VaultName -Name $keyVaultSecretName
    
    $pfxCertObject = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @([Convert]::FromBase64String($secret.SecretValueText),"",[System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
    
    $pfxPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 50 | % {[char]$_})
    
    $currentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
    [Environment]::CurrentDirectory = (Get-Location -PSProvider FileSystem).ProviderPath
    [io.file]::WriteAllBytes(".\KeyVaultCertificate.pfx", $pfxCertObject.Export([System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12, $pfxPassword))
    
    Write-Host "Created an App Service Certificate copy at: $currentDirectory\KeyVaultCertificate.pfx"
    Write-Warning "For security reasons, do not store the PFX password. Use it directly from the console as required."
    Write-Host "PFX password: $pfxPassword" 
    
    16.12.2020
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..