Validation of JWT based on the x5c header field is not working
See original GitHub issueI have the following JWT which was signed with an X509 certificate. The signing certificates itself is embedded in the x5c
field of the JWT header.
eyJhbGciOiJSUzI1NiIsImtpZCI6IjM2ODZEMEQ2NzgyQzUyQ0U1NjI5RThENkI4MjFCMkU2RENGMjE4RkYiLCJ4NXQiOiJOb2JRMW5nc1VzNVdLZWpXdUNHeTV0enlHUDgiLCJ0eXAiOiJKV1QiLCJ4NWMiOlsiTUlJSGZEQ0NCV1NnQXdJQkFnSVFiMEd0ZG5YdXRZWXM2VSt1Yy9TbEtqQU5CZ2txaGtpRzl3MEJBUXNGQURDQm56RUxNQWtHQTFVRUJoTUNSRVV4RHpBTkJnTlZCQWdNQmtKaGVXVnliakVSTUE4R0ExVUVCd3dJVFhWbGJtTm9aVzR4RURBT0JnTlZCQW9NQjFOcFpXMWxibk14RVRBUEJnTlZCQVVUQ0ZwYVdscGFXa0l5TVIwd0d3WURWUVFMREJSVGFXVnRaVzV6SUZSeWRYTjBJRU5sYm5SbGNqRW9NQ1lHQTFVRUF3d2ZVMmxsYldWdWN5QkpjM04xYVc1bklFTkJJRVZGSUVGMWRHZ2dNakF5TURBZUZ3MHlNREV3TURjd09EUXdORFphRncweU16RXdNRGN3T0RRd05EWmFNR0V4RVRBUEJnTlZCQVVUQ0Zvd01ESk5OelpCTVE0d0RBWURWUVFxRXdWU2RXWjFjekVSTUE4R0ExVUVCQk1JUW5WelkyaGhjblF4RURBT0JnTlZCQW9UQjFOcFpXMWxibk14RnpBVkJnTlZCQU1URGtKMWMyTm9ZWEowSUZKMVpuVnpNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXVlV0MzR0IwdHRPaFNtZlBGQWJ5cVc0YjRjWG1nUUJBOGJzalU2bDNvT0JqczV6M1pYWFlMM3FsdTA5Mm8rcERKdEFMVGpYNmlaQ3dwWlJuQURYU1pVeWpWNm1XZEF6aWxqdG1FVXlZZG56NnhzQ1lpR2NHQzdaMTdNMmQ2OXFBdEl2d2hGeWE4alVZbDB5QTJGK1ppb1ViaStQUmhtdFBSZmg1bi80RXp4b1J5bG0xVlJzNkdQcTFRMjNBZTdPbGhBOGxxVFg2YkJZdVYwQ0E4Q2tTWjB3MzBaSXJGUTJ6UVZHSEJwTm8rcjNiSlRWdFNRZDduaUNTNkN5bFVEWWI4NGZ4emFPMmZoczJXMU5TcEI5SzVpR1dFaWpNQ0I2Ti9kTTMvMFVTbTJMSmt2cExKK2VQUlkwQ1I2TVptZmdxQ3l2QVFVWFRxdmFOZ2krOXNSUlNmUUlEQVFBQm80SUM3ekNDQXVzd0tRWURWUjBsQkNJd0lBWUlLd1lCQlFVSEF3SUdDQ3NHQVFVRkJ3TUVCZ29yQmdFRUFZSTNGQUlDTUI4R0ExVWRJd1FZTUJhQUZOYnYrNmZuS3JIQVhVeG9oY0l0ajFabWZvTHVNSUgzQmdnckJnRUZCUWNCQVFTQjZqQ0I1ekF5QmdnckJnRUZCUWN3QW9ZbWFIUjBjRG92TDJGb0xuTnBaVzFsYm5NdVkyOXRMM0JyYVQ5YVdscGFXbHBDTWk1amNuUXdRUVlJS3dZQkJRVUhNQUtHTld4a1lYQTZMeTloYkM1emFXVnRaVzV6TG01bGRDOURUajFhV2xwYVdscENNaXhNUFZCTFNUOWpRVU5sY25ScFptbGpZWFJsTUVrR0NDc0dBUVVGQnpBQ2hqMXNaR0Z3T2k4dllXd3VjMmxsYldWdWN5NWpiMjB2UTA0OVdscGFXbHBhUWpJc2J6MVVjblZ6ZEdObGJuUmxjajlqUVVObGNuUnBabWxqWVhSbE1DTUdDQ3NHQVFVRkJ6QUJoaGRvZEhSd09pOHZiMk56Y0M1emFXVnRaVzV6TG1OdmJUQkdCZ05WSFNBRVB6QTlNRHNHRFNzR0FRUUJvV2tIQWdJREFRRXdLakFvQmdnckJnRUZCUWNDQVJZY2FIUjBjSE02THk5M2QzY3VjMmxsYldWdWN5NWpiMjB2Y0d0cEx6Q0J5Z1lEVlIwZkJJSENNSUcvTUlHOG9JRzVvSUcyaGlab2RIUndPaTh2WTJndWMybGxiV1Z1Y3k1amIyMHZjR3RwUDFwYVdscGFXa0l5TG1OeWJJWkJiR1JoY0RvdkwyTnNMbk5wWlcxbGJuTXVibVYwTDBOT1BWcGFXbHBhV2tJeUxFdzlVRXRKUDJObGNuUnBabWxqWVhSbFVtVjJiMk5oZEdsdmJreHBjM1NHU1d4a1lYQTZMeTlqYkM1emFXVnRaVzV6TG1OdmJTOURUajFhV2xwYVdscENNaXh2UFZSeWRYTjBZMlZ1ZEdWeVAyTmxjblJwWm1sallYUmxVbVYyYjJOaGRHbHZia3hwYzNRd0hRWURWUjBPQkJZRUZFaEVhQmM0S1gzRG94aVB1dUd3aFF2RFhldVdNQTRHQTFVZER3RUIvd1FFQXdJSGdEQlJCZ05WSFJFRVNqQklvQ29HQ2lzR0FRUUJnamNVQWdPZ0hBd2FjblZtZFhNdVluVnpZMmhoY25SQWMybGxiV1Z1Y3k1amIyMkJHbkoxWm5WekxtSjFjMk5vWVhKMFFITnBaVzFsYm5NdVkyOXRNQXdHQTFVZEV3RUIvd1FDTUFBd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dJQkFDdEk4UDVvQTR1UG9JWVpLV0tYNUJvSlZsaTArOFhuckM5L0xIb29NYlI1WVJyekhCdC8wbFc0d2p4OHJjY2thTGN5ZzZyVXJIYXpra3k2dWRCaDVBTlBmSE9HQ0M4b3N3REV6UFQveUtZazBqcUx2eStmckVNNFlrZk5aSTUzYXVXYTJXNlYxNUxIYkVyVzJCOU9SS2lOdEsrYmtIa09zR0xuWlFFaXFGQ3RZL3I1cy9XNVdSaGlNb1ppUTZsMUh0ZXNVSWZIR1piNFhXVGlwSUd3RnltU2RrM2xpQWorekJqWmoydm15MURZVHVuQytSUmxHZFpnemkrRC9LK1NoQ240YjZWR2ZPR3AxMFVLNUtTbm8zL3lhSTY2aXNBNXZtbFlJRk8xWkYvMGhqRnl6NUdVeW9NdDFJRk9qcFA3ZS9kaEtiUElsWHA1aDJ3c3hrNjJKRlBRN3hpNHBIYlpvUlBMbVE1RkVoZVI4UXpCZHJuMTJuWnp2bHk0dXhiaWlISStVMFlaUnEzVm1YRnorYzJIcHM3SEVtR3ArUmhaRXVDcit1NklobDMySTljTlBMMVNKZTh3aW04b2p6bmFaRmZoenlYbDl0cnppSHJ6NUdOdFdEZzRNWkhlL0pTN0tRNC95eHVqL2w4cDBwTHdXaU9Ycnl0WEZsSGx1b0tka2J2cXlCRGdvb25iSjBpSzhVMDE1WnR2MVYwc2pBbDYzYnFZMDZuaHYvZUxWemorOWE1V1FHNHE4aTk2RkNGNGJqOUFtK0ZzRDU5MnUwM3M2VVdUa01kbWMrRmJ0V0xXdDlrL25hWjk0ZFRWRklQaDBFTG5XeWNTYWlySnA0LzNvRkpPNjJkWkRpc1ZCbENiQmJUZ1NPS1VaeVdJMVJ6NlRTVXp3UFVHS0REVCJdfQ.eyJjb250ZW50IjoiVGVzdCBkYXRhIiwibmJmIjoxNjAyNzUwMjI1LCJleHAiOjE2MDI3NTA1MjUsImlhdCI6MTYwMjc1MDIyNSwiaXNzIjoiQ049QnVzY2hhcnQgUnVmdXMsIE89U2llbWVucywgU049QnVzY2hhcnQsIEc9UnVmdXMsIFNFUklBTE5VTUJFUj1aMDAyTTc2QSJ9.Ax1E_6ZqgdstOmYBxO2bSITpppW_K8JN4f_kAcUPBc77ucaZ4419bzOrx9eF9ib22nTa2JDRivGa_sUfs3W4OjjoEiXatzzTXWZYFcpAz60CYRuvgpu1rKOl4T5aiz5JAyVOoFWopDGjKPYIM2Hkg51JgDKcYDcX-JNBoH8ZEyXSkzhHwjwnDMZf6RT1RLCIpb4urcrfXl7nyJiwyLRzwAaO9gSdJiTPRGm5qrcmTy93eBABb0zjp0HbTbfqlMcHQozPB7ARAkn5d60BqRj2CrOMGak4yBzliYUVJqmkYZAtZ2NK-3tMZXY_Z8fRDiOJS4ys1Up3Zum8f-X2ZSeJog
I’m trying to validate this JWT with the following code:
var handler = new JwtSecurityTokenHandler();
var validationParameters =
new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
};
SecurityToken validatedSecurityToken = null;
var cp = handler.ValidateToken(jwt, validationParameters, out validatedSecurityToken);
This results in an exception:
Microsoft.IdentityModel.Tokens.SecurityTokenSignatureKeyNotFoundException: ‘IDX10501: Signature validation failed. Unable to match key: kid: ‘System.String’. Exceptions caught: ‘System.Text.StringBuilder’. token: ‘System.IdentityModel.Tokens.Jwt.JwtSecurityToken’.’
As an alternative approach, I did try to extract the certificate from the x5c field in the header
JwtSecurityToken outerJWT = handler.ReadJwtToken(jwt);
JwtHeader header = outerJWT.Header;
header.X5c
but this is not working either, since there is no X5c
field in the JwtHeader
class.
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (7 by maintainers)
Top GitHub Comments
@shadow-cs thank you for your feedback. I’ll try this. Did you see my PR #1543 ? This one line of code would make the x5c header directly available without casting.
@gergoszekeresnuance x5c, x5u, where the key is inside the JWT, is not supported directly. Our validation logic expects that TokenValidationParameters either has the signing keys OR a delegate is used.
Microsoft’s WCF runtime would validate SAML token signatures that contained x5c, but we made a design decision to require all accepted keys to be available.