11

The Identity Server 4 documentation (here http://docs.identityserver.io/en/latest/topics/crypto.html?highlight=data%20protection ) discusses signing keys and validation keys. I know that the signing key is configured using

AddSigningCredential(<X509Certificate2>)

and there are two APIs for validation keys

AddValidationKey(<X509Certificate2>)
AddValidationKeys(<Microsoft.IdentityModel.Tokens.AsymmetricSecurityKey[]>) 

The document talks about signing key rollover and adding multiple validation keys to the discovery document. Questions:

Pang
  • 8,605
  • 144
  • 77
  • 113
Brad Cote
  • 113
  • 1
  • 8

1 Answers1

10

IdentityServer uses asymmetric encryption. Asymmetric encryption means you have a public key and a private key. The public key is shared (obviously) and is used only to encrypt. The private key is, well, private. It should be strictly protected and never shared, and it's used to decrypt. The signing key is your public key, while the validation key is your private key, so yes, you need both. An X509Certicate can be used because certificates employ both public and private keys, but ultimately, IdentityServer is just using the cert to get at the keys.

The AddValidationKeys (plural) method is used explicitly for key rollover. Your cert, for example, will likely expire after one year (the default in most cases). At the end of that period, you would replace it with the new cert. However, clients may still have access tokens and such encrypted via the public key from the previous cert, and IdentityServer would need the private key from the previous cert to decrypt that. Using this method, you can add the previous keys only for the purpose of validating material IdentityServer can't validate with the current keys.

Data Protection is really totally separate. It too uses public and private keys to do what it does, so technically, you could use the same keys for IdentityServer as well. However, it's better to keep your keys restricted to unique purposes. That way, if you do get compromised, you aren't completely compromised, and can somewhat limit the scope of the potential leak.

Chris Pratt
  • 207,690
  • 31
  • 326
  • 382
  • Thank you Chris - this helps very much. The reason I thought the Data Protection keys were related is because whenever we published IdentityServer4, users who had logged in prior to the publish would get a IDX10500 error. If the user refreshed the browser, they would proceed to the login page with no errors. When we added .AddDataProtection().PersistKeyToAzureBlobStorage these errors appear to have stopped (we are still testing). More details are in this question https://stackoverflow.com/questions/52065850/idx10500-signature-validation-failed-only-after-publish – Brad Cote Aug 29 '18 at 15:47
  • By default Data Protection keys are persisted in-memory. When you publish a new version of the app, it is necessarily stopped and then restarted to reflect those changes. When the app stops, anything in memory goes with it, so when it's restarted you have new keys. Persisting the keys to an actual persistent store like Azure blob storage, obviously solves this problem, as the keys survive app restarts then. – Chris Pratt Aug 29 '18 at 15:50
  • Thank you Chris - I suspected this, but could not find any Microsoft documentation that stated the keys are regenerated if not stored. Thank you again. – Brad Cote Aug 29 '18 at 16:29
  • 2
    One problem in the above answer is that "The signing key is your Private key, not the public key, while the validation key is your public key, not the private key. – Kashif Hanif Mar 24 '19 at 12:43
  • No it's the opposite. Public key is always for encrtyption because only the owner of the private key can decrypt. That's the whole point of asymmetric encryption. – Chris Pratt May 02 '19 at 05:21
  • 2
    @Haukman: one thing is encryption and another is signing with, well, a signature. Like Chris said, the encryption is made with the public so only the owner of the private key can decrypt it. The signature is made with the private one, so only that person can sign it, and everybody else can verify that that signature was made only by the owner of the private key. Encryption and signature work at the inverse between them. IdentityServer doesn't encrypt JWTs, it just needs to sign them so that anyone can verify them and know that they were not tampered with. – CesarD Jun 09 '19 at 07:03
  • 1
    Well, technically, yes. As I said in the answer, the purpose of AddValidationKeys is for key rollover. It allows old expired keys to still be used, or in this case, an old cert. If the cert is the same as what's currently being used for signing, it would be unnecessary to add the same one here. However, this should happen naturally over time. You wouldn't generate two certs at the same time for each. – Chris Pratt Mar 30 '20 at 17:58
  • @ChrisPratt sorry, I've deleted my previous question to which you answered (the question was if we are supposed to have two different X509Certificates for `AddSigningCredential` and `AddValidationKey?`) – Pedro Faustino Mar 30 '20 at 18:42
  • What got me confused was this "The signing key is your public key, while the validation key is your private key, so yes, you need both". The way I understood it was that the `AddSigningCredential` should have the public key and the `AddValidationKey` should have the private key, which led me to assume that they both had to share the same certificate, otherwise the public/private pair would not work. – Pedro Faustino Mar 30 '20 at 18:42
  • 1
    After reading this [article](https://brockallen.com/2019/08/09/identityserver-and-signing-key-rotation/) I saw that `AddValidationKey` should be used when we want additional keys to be included (key rollover), meaning that `AddSigningCredential` can be used alone if we just have one cert that is going to be used for signing (although we should prepare for the future and aim for key rollover). Also, your explanation got me clarified @ChrisPratt, thank you. – Pedro Faustino Mar 30 '20 at 18:42
  • is there any example of using DataProtection key for IdentityServer? couldn't seem to find any documentation on that as well – liang Jun 15 '20 at 11:28
  • It's no different. Data Protection is a bass API. Anything that uses that API uses the same config. – Chris Pratt Jun 15 '20 at 11:36
  • 1
    "The signing key is your public key, while the validation key is your private key..." This part does not sound correct to me. The purpose of signing is to ensure that the token was issued by the trusted party. If the public key was for signing then anybody could sign it. Conversely, the validation key should be the public key because you want parties other than the issuer to be able to validate the key. – yogibear Oct 19 '20 at 12:45
  • Well, that article which @PedroFaustino linked in his comment makes it complete. – Learner Oct 20 '20 at 09:52
  • @ChrisPratt Downvoting. I'll upvote once it's fixed, but this answer in it's current state is definitely wrong. As others have said you have the public and private keys mixed up. Signing != encryption. And the validation key is definitely public according to the [docs](https://docs.identityserver.io/en/release/topics/crypto.html) which state that the validation key is published to the discovery document. Once it's fixed it will be a good answer. – Alex Schimp Jan 13 '21 at 19:28