简体   繁体   English

使用 IdentityServer4 和 DataProtection API 进行令牌签名

[英]Using IdentityServer4 with DataProtection API for token signing

I have an authentication/authorization server based on IS4 + Net Core 3.1.我有一个基于 IS4 + Net Core 3.1 的身份验证/授权服务器。 Since this Identity Service interacts with some new as well as some quite legacy applications, it also creates 2 different authentication cookies plus tokens.由于此身份服务与一些新的以及一些非常旧的应用程序交互,它还会创建 2 个不同的身份验证 cookie 和令牌。 We are are currently using DPAPI to sign cookies and some other sensitive information we need.我们目前正在使用 DPAPI 来签署 cookie 和我们需要的一些其他敏感信息。

So far, we've been using a certificate as a SigningCredential in IS4, but now I want to be able to use DPAPI so that key rotation is managed automatically, or at least, we can manage them all in a single place.到目前为止,我们一直在 IS4 中使用证书作为 SigningCredential,但现在我希望能够使用 DPAPI 以便自动管理密钥轮换,或者至少,我们可以在一个地方管理它们。

Based on IS4 docs I just need to implement ISigningCredentialStore and IValidationKeysStore , however I am not quite familiar with how this is managed.基于IS4 文档,我只需要实现ISigningCredentialStoreIValidationKeysStore ,但是我不太熟悉这是如何管理的。 I've got an approximation like this (I know, it is almost worhtless at this point):我有一个这样的近似值(我知道,在这一点上它几乎毫无价值):

private class CustomSigningCredentialStore : ISigningCredentialStore
{
    private readonly IKeyManager _keyManager;

    public CustomSigningCredentialStore(IKeyManager keyManager) =>
        _keyManager = keyManager;

    public Task<SigningCredentials> GetSigningCredentialsAsync()
    {
        // For the sake of simplicity, lets assume
        // that this is the correct one
        var currentKey = _keyManager.GetAllKeys().ElementAt(0);

        // Complete

        return new SigningCredentials(...);
    }
}

private class CustomValidationKeysStore : IValidationKeysStore
{
    private readonly IKeyManager _keyManager;

    public CustomValidationKeysStore(IKeyManager keyManager) =>
        _keyManager = keyManager;

    public Task<IEnumerable<SecurityKeyInfo>> GetValidationKeysAsync()
    {
        var keys = _keyManager.GetAllKeys();

        // Complete

        return keys.Select(key => new SecurityKeyInfo(...));
    }
}

I am stuck with this to be honest, I don't know how to map current keys generated by DPAPI, which looks like this:老实说,我坚持这个,我不知道如何映射 DPAPI 生成的当前密钥,它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<key id="32f6d43e-97a9-4c4b-b108-e11f65e05cc4" version="1">
  <creationDate>2020-07-31T00:00:00.0886417Z</creationDate>
  <activationDate>2020-07-31T00:00:00.086065Z</activationDate>
  <expirationDate>2020-08-30T00:00:00.086065Z</expirationDate>
  <descriptor deserializerType="Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=3.1.8.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
    <descriptor>
      <encryption algorithm="AES_256_CBC" />
      <validation algorithm="HMACSHA256" />
      <masterKey p4:requiresEncryption="true" xmlns:p4="http://schemas.asp.net/2015/03/dataProtection">
        <value>h1/a9G8i78kpnHBTEsisA5rk5ppm8vzByquAT2CO1OFnYHCX/eT/yfcFM/JigYkSDj+dupBz9ZZ7/XFMu/uWxg==</value>
      </masterKey>
    </descriptor>
  </descriptor>
</key>

Any insight will be extremelly appreciated.任何见解将不胜感激。

I recently implemented my own key-ring store that stores the keys in Azure Key Vault and I blogged about that here:我最近实现了我自己的密钥环存储,将密钥存储在 Azure Key Vault 中,我在这里写了博客:

Storing the ASP.NET Core Data Protection Key Ring in Azure Key Vault 将 ASP.NET Core 数据保护密钥环存储在 Azure Key Vault 中

For token signin that you ask about, I first load them from Azure Key Vault and then add it manually to IdentitySever, like this (using some custom extension methods):对于您询问的令牌登录,我首先从 Azure Key Vault 加载它们,然后手动将其添加到 IdentitySever,如下所示(使用一些自定义扩展方法):

// First we load the certificates (that contains the private keys) from Azure Key Vault
var rsaCert = KeyVaultExtensions.LoadCertificate(config, "rsa");
       
//Add RS256 (RSASSA-PKCS1-v1_5 using SHA-256)
builder.AddSigningCredential(rsaCert, "RS256");

Also, I wouldn't try to use the keys form DPAPI as signing keys, because those keys are not suitable for singing tokens.此外,我不会尝试使用 DPAPI 形式的密钥作为签名密钥,因为这些密钥不适合用于唱令牌。 For token signing you want RSA or ECDSA keys and the simplest is to store them in Azure Key Vault for example.对于令牌签名,您需要 RSA 或 ECDSA 密钥,例如,最简单的方法是将它们存储在 Azure Key Vault 中。 DPAPI you should configure and store outside your application, but that is only used for protecting the session cookies.您应该在应用程序之外配置和存储 DPAPI,但这仅用于保护会话 cookie。 Not signing tokens.不签署令牌。

I highly doubt you can use the data protection to manage and rotate the signing keys for you.我非常怀疑您是否可以使用数据保护来管理和轮换签名密钥。 The keys issued by DPAPI and stored in the key ring are symmetrical while the keys for key signing needs to be asymmetrical (public/private RSA/ECDSA keys). DPAPI 发布并存储在密钥环中的密钥是对称的,而用于密钥签名的密钥需要是非对称的(公钥/私钥 RSA/ECDSA 密钥)。 Basically, they are not compatible.基本上,它们不兼容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM