Как получить сертификат KeyVault на отпечатке - PullRequest
1 голос
/ 31 января 2020

Я пытаюсь сделать что-то простое (по крайней мере, я ожидаю, что это будет), как получить сертификат на его основе Thumbprint в Azure KeyVault?

Наша система извлекает подписанный JWToken, и в его заголовке содержится «ребенок», содержащий отпечаток сертификата, подписанный JWToken. Мне нужно найти сертификат на основе этого отпечатка для проверки. С Azure KeyVault SDK (ядро C#), похоже, нет способа извлечь сертификат на основе этого Thumbprint.

Поскольку могут существовать разные версии сертификата (каждая из которых имеет разный отпечаток), я не могу использовать await client.GetSecretAsync(KvBaseUrl, CertificateName). Я создал следующий код:

public async static Task<X509Certificate2> GetCertificateByThumbprintAsync(this KeyVaultClient client, string kvBaseUrl, string certificateName, string thumbprint )
{
    var allVersionsAsGetTasks = (await client.GetCertificateVersionsAsync(kvBaseUrl, certificateName).ConfigureAwait(false))
        .Select(x => client.GetCertificateAsync(x.Identifier.Identifier))
        .ToList();

    var allCertificates = await Task.WhenAll(allVersionsAsGetTasks).ConfigureAwait(false);

    var correctCertificate = allCertificates.Select(x => new X509Certificate2(x.Cer))
        .FirstOrDefault(x => x.Thumbprint == thumbprint);

    if (correctCertificate == null)
        throw new Exception($"Certificate with thumbprint '{thumbprint}' was not found");

    return correctCertificate;
}

Я получаю сертификат, но это похоже на большую работу и множество ненужных вызовов KeyVault (Task.WhenAll code).

Есть ли более простой способ сделать это?

Код client.GetCertificateVersionsAsync(..) возвращает CertificateItem, который содержит Свойство X509Thumbprint типа byte[]. Кажется, я не могу преобразовать byte[] как строку. Я пробовал Base64 и UTF8, но оба дают мне странный результат, не содержащий отпечаток.

Обновление

Благодаря коллеге мы нашли более быстрый способ получения правильный сертификат


public async static Task<CertificateBundle> GetCertificateByThumbprintAsync(this KeyVaultClient client, string kvBaseUrl, string certificateName, string thumbprint)
{
    var certificateVersion = (await client.GetCertificateVersionsAsync(kvBaseUrl, certificateName).ConfigureAwait(false))
        .FirstOrDefault(x => BitConverter.ToString(x.X509Thumbprint).Replace("-", "") == thumbprint);

    if (certificateVersion == null)
        throw new Exception($"Certificate with thumbprint '{thumbprint}' was not found");

    return await client.GetCertificateAsync(certificateVersion.Identifier.Identifier);
}

Обновление 2 Мы используем Azure Управляемые удостоверения для доступа к KeyVault. Мы используем следующий код:

private async Task<KeyVaultClient> GetClientAsync()
{
    var provider = new AzureServiceTokenProvider();

    logger.LogInformation("Trying to retrieve a token for KeyVault communication.");

    try
    {
        await provider.GetAccessTokenAsync("https://vault.azure.net").ConfigureAwait(false);

        logger.LogInformation("Token for KeyVault received");
    }
    catch (Exception)
    {
        logger.LogError("Could not retrieve access for KeyVault communication.");
        throw;
    }

    return new KeyVaultClient(new AuthenticationCallback(provider.KeyVaultTokenCallback));
}
...