"The signature is invalid" error on Linux through HTTP - JWT Authentication
See original GitHub issueFrom @hasan-hasanov on August 14, 2018 13:23
In our project we are using JWT authentication and ran into the following problem on Linux platform. When I am making requests over HTTPS everything is fine and working. However when I disable SSL from Properties -> Debug window I am getting 401 status code with error: “The signature key is invalid”.
In Windows platform everything is fine.
Here is the logic on how the token is generated:
[Route("/api/token")]
public class TokenController : Controller
{
[HttpGet("get")]
public IActionResult GetToken()
{
string token = GenerateEncodedToken();
return Ok(token);
}
[NonAction]
public string GenerateEncodedToken()
{
var user = new { username = "test@test.bg" };
var claims = new[]
{
new Claim(type: JwtRegisteredClaimNames.Sub, value: user.username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
using (RSA rsa = RSA.Create())
{
rsa.LoadFromXmlString("<RSAKeyValue><Modulus>6smCiPS0Nn9f1JE701SO9oeQ1cpVXqZQs3V4ENPXM+P6RNQjPz919dSBXAJ6jjJ8fkX2gpp3YKQ6/Ou+Dl9NE6CszvHpRArquMQV8+F9Qa0EDeTdBJpmLysBmTU4B3sZDt34QvS1+yr6vNWgkuIquZoeud6O5xdS3B6q1JZW9qdM3a2vVVg+qZTHTI2zczi2rINxVi8q7WqGFheOXYAqDWua2+LZZaFHPgR6BbFwhLorPbuRIkj0b6Z9opwv6qLjcbjw7DINPzFn4RJfMyGzHq0eje75NfIiynJs45m8AXGXeYvYlslVXwkVL1A5fyoEFY/TRTQ7hbvYChyxDQV3YQ==</Modulus><Exponent>AQAB</Exponent><P>7h/rJSePC0GY+i5PRrJJAaOz0PQ0FfDsK2CiuQVtMxEt7v2xMFtAQcWSGfxEzHMVHF5g4d4Zd9nc6vK8OlajSZVcR7nK9XLpCUisDu2zV1QlVoLuQ2+Y7Ybl3AEI2vvj8xcG55IzhZo4U7iRV/BhzupiVkw6insKi5//W7b+Ifs=</P><Q>/Gl0E9v20eOEBKIX7Jyk2MvNNk7QUcNZMpMbRy3xPQqHF4dlFBw7AsxnC316dliRQrE50zaVaH2B10MbXmFiEnA1ofczdxb1+URa8wO0dPDgXGTL4x/33leKVkplpVHKFJiqK1NmIZ4w73z2/1Dny+L57xV5Qiu6QWqmNWep6VM=</Q><DP>k3/b9RjK50sLyjRzULRQup4/XPhXZxvj/n6ObRMqcA59KGOmpPBxHgyWklgL+aRzeC4Rzvb3SaD+0d3nsC9IV+UX0yoHyQATz3dfdKPSig6KTkst8UGoNcFwklVludd7fHFQCpMqLOC5cUqLZTB2NWhD33a6cFsEzjYeRB5Wzo8=</DP><DQ>xEjtL5RaeBXJUCENIb8eoki6KIVZknurHZ0wFUYw1xscurtbaywY57A0YccOOIHfVFGleg50WXFgSxmwatCoB1ajHnSx3OZKGbGCWICFEHtQvgjUVKdDhe/lb/0i1lCoKSQfENomDfaKb3JqUVmFKBQ18CpuxXpjuQNKhTU7+Gk=</DQ><InverseQ>nSOKlifw5wndoaRlakM4vMiq6I+sMMzx7PfIowSNzTp4+98OS08pBlOFfgTYL2PG/5n7ruChEex+ARE2QXxbE1nvu6SYpkzq+PHZXPVLGcEGpEnIUmU05dggajW/8Pu4vn1L8zVevBy+9A3sptP6O2CXxLqOIYKdakvoiSOSgIQ=</InverseQ><D>wVvlYg9NX1h1PqXBRGDuQEATWs6AkiucaL9Ee29LW1PUp9yhjpQf/K3fPzxXXEZd2syZoKO/ztpSLjuj0UhRPOnlh6UY+82V00bB4ZEBzBXGMf8aupDBuPTNIzT+CMMrNuA9dj78pHaX+u5giLc0gphX17FftRezSM8E14Fc61H28gGQVgBSCXtwpDY88CaqzJ/xZgmgr65XKDri5vXRoixAbF+eA6dQKgpGvd5cI4EXdaHgOF99TyW8SG57KtcrUTmvLeVt5AaQpq+ZROjqIrRL5py4IwglQsbvJKTuTTSwdYfzqeHfpbWXgwNH4revXSQAJa1/IacI6q1bob5UpQ==</D></RSAKeyValue>");
var token = new JwtSecurityToken
(
issuer: "Issuer",
audience: "Audience",
claims: claims,
expires: DateTime.UtcNow.AddDays(10),
notBefore: DateTime.UtcNow,
signingCredentials: new SigningCredentials(new RsaSecurityKey(rsa), SecurityAlgorithms.RsaSha256Signature)
);
string encodedToken = new JwtSecurityTokenHandler().WriteToken(token);
return encodedToken;
}
}
}
And here is the logic on my Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
SecurityKey signingKey;
using (RSA publicRsa = RSA.Create())
{
publicRsa.LoadFromXmlString("<RSAKeyValue><Modulus>6smCiPS0Nn9f1JE701SO9oeQ1cpVXqZQs3V4ENPXM+P6RNQjPz919dSBXAJ6jjJ8fkX2gpp3YKQ6/Ou+Dl9NE6CszvHpRArquMQV8+F9Qa0EDeTdBJpmLysBmTU4B3sZDt34QvS1+yr6vNWgkuIquZoeud6O5xdS3B6q1JZW9qdM3a2vVVg+qZTHTI2zczi2rINxVi8q7WqGFheOXYAqDWua2+LZZaFHPgR6BbFwhLorPbuRIkj0b6Z9opwv6qLjcbjw7DINPzFn4RJfMyGzHq0eje75NfIiynJs45m8AXGXeYvYlslVXwkVL1A5fyoEFY/TRTQ7hbvYChyxDQV3YQ==</Modulus><Exponent>AQAB</Exponent><P>7h/rJSePC0GY+i5PRrJJAaOz0PQ0FfDsK2CiuQVtMxEt7v2xMFtAQcWSGfxEzHMVHF5g4d4Zd9nc6vK8OlajSZVcR7nK9XLpCUisDu2zV1QlVoLuQ2+Y7Ybl3AEI2vvj8xcG55IzhZo4U7iRV/BhzupiVkw6insKi5//W7b+Ifs=</P><Q>/Gl0E9v20eOEBKIX7Jyk2MvNNk7QUcNZMpMbRy3xPQqHF4dlFBw7AsxnC316dliRQrE50zaVaH2B10MbXmFiEnA1ofczdxb1+URa8wO0dPDgXGTL4x/33leKVkplpVHKFJiqK1NmIZ4w73z2/1Dny+L57xV5Qiu6QWqmNWep6VM=</Q><DP>k3/b9RjK50sLyjRzULRQup4/XPhXZxvj/n6ObRMqcA59KGOmpPBxHgyWklgL+aRzeC4Rzvb3SaD+0d3nsC9IV+UX0yoHyQATz3dfdKPSig6KTkst8UGoNcFwklVludd7fHFQCpMqLOC5cUqLZTB2NWhD33a6cFsEzjYeRB5Wzo8=</DP><DQ>xEjtL5RaeBXJUCENIb8eoki6KIVZknurHZ0wFUYw1xscurtbaywY57A0YccOOIHfVFGleg50WXFgSxmwatCoB1ajHnSx3OZKGbGCWICFEHtQvgjUVKdDhe/lb/0i1lCoKSQfENomDfaKb3JqUVmFKBQ18CpuxXpjuQNKhTU7+Gk=</DQ><InverseQ>nSOKlifw5wndoaRlakM4vMiq6I+sMMzx7PfIowSNzTp4+98OS08pBlOFfgTYL2PG/5n7ruChEex+ARE2QXxbE1nvu6SYpkzq+PHZXPVLGcEGpEnIUmU05dggajW/8Pu4vn1L8zVevBy+9A3sptP6O2CXxLqOIYKdakvoiSOSgIQ=</InverseQ><D>wVvlYg9NX1h1PqXBRGDuQEATWs6AkiucaL9Ee29LW1PUp9yhjpQf/K3fPzxXXEZd2syZoKO/ztpSLjuj0UhRPOnlh6UY+82V00bB4ZEBzBXGMf8aupDBuPTNIzT+CMMrNuA9dj78pHaX+u5giLc0gphX17FftRezSM8E14Fc61H28gGQVgBSCXtwpDY88CaqzJ/xZgmgr65XKDri5vXRoixAbF+eA6dQKgpGvd5cI4EXdaHgOF99TyW8SG57KtcrUTmvLeVt5AaQpq+ZROjqIrRL5py4IwglQsbvJKTuTTSwdYfzqeHfpbWXgwNH4revXSQAJa1/IacI6q1bob5UpQ==</D></RSAKeyValue>");
signingKey = new RsaSecurityKey(publicRsa);
}
TokenValidationParameters parameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = "Issuer",
ValidAudience = "Audience",
ValidateAudience = true,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
services.AddAuthentication(o =>
{
o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = parameters;
options.RequireHttpsMetadata = false;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
}
Finally I am using an extension method for RSA key loading LoadFromXmlString
public static class RsaExtension
{
public static void LoadFromXmlString(this RSA rsa, string xmlString)
{
RSAParameters parameters = default(RSAParameters);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue"))
{
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
switch (node.Name)
{
case "Modulus": parameters.Modulus = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "Exponent": parameters.Exponent = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "P": parameters.P = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "Q": parameters.Q = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "DP": parameters.DP = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "DQ": parameters.DQ = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "InverseQ": parameters.InverseQ = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
case "D": parameters.D = string.IsNullOrEmpty(node.InnerText) ? null : Convert.FromBase64String(node.InnerText); break;
}
}
}
else
{
// Unauthorized
throw new Exception("Invalid XML RSA key.");
}
rsa.ImportParameters(parameters);
}
}
I have tried setting to false the following properties in my startup: ValidateIssuerSigningKey, ValidateIssuer, ValidateAudience.
I have also tried setting the RequireHttpsMetada to true and false - still nothing.
So far the only thing that works is making requests with SSL since this application will be in our private network we do not want that.
This is the stack trace from the output WIndow
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[1]
Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId:
'.
Exceptions caught:
'System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.Crypto.RsaVerify(Int32 type, Byte& m, Int32 m_len, Byte& sigbuf, Int32 siglen, SafeRsaHandle rsa)
at Interop.Crypto.RsaVerify(Int32 type, ReadOnlySpan`1 m, ReadOnlySpan`1 sigbuf, SafeRsaHandle rsa)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(ReadOnlySpan`1 hash, ReadOnlySpan`1 signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(Byte[] hash, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Int32 offset, Int32 count, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.Verify(Byte[] input, Byte[] signature)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
'.
token: '{"alg":"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256","typ":"JWT"}.{"sub":"test@test.bg","jti":"ee362edf-95e5-42d7-8261-fd144c398791","nbf":1534252018,"exp":1535116018,"iss":"Issuer","aud":"Audience"}'.
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Failed to validate the token.
Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId:
'.
Exceptions caught:
'System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.Crypto.RsaVerify(Int32 type, Byte& m, Int32 m_len, Byte& sigbuf, Int32 siglen, SafeRsaHandle rsa)
at Interop.Crypto.RsaVerify(Int32 type, ReadOnlySpan`1 m, ReadOnlySpan`1 sigbuf, SafeRsaHandle rsa)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(ReadOnlySpan`1 hash, ReadOnlySpan`1 signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(Byte[] hash, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Int32 offset, Int32 count, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.Verify(Byte[] input, Byte[] signature)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
'.
token: '{"alg":"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256","typ":"JWT"}.{"sub":"test@test.bg","jti":"ee362edf-95e5-42d7-8261-fd144c398791","nbf":1534252018,"exp":1535116018,"iss":"Issuer","aud":"Audience"}'.
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
Bearer was not authenticated. Failure message: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId:
'.
Exceptions caught:
'System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.Crypto.RsaVerify(Int32 type, Byte& m, Int32 m_len, Byte& sigbuf, Int32 siglen, SafeRsaHandle rsa)
at Interop.Crypto.RsaVerify(Int32 type, ReadOnlySpan`1 m, ReadOnlySpan`1 sigbuf, SafeRsaHandle rsa)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(ReadOnlySpan`1 hash, ReadOnlySpan`1 signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(Byte[] hash, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Int32 offset, Int32 count, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.Verify(Byte[] input, Byte[] signature)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
'.
token: '{"alg":"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256","typ":"JWT"}.{"sub":"test@test.bg","jti":"ee362edf-95e5-42d7-8261-fd144c398791","nbf":1534252018,"exp":1535116018,"iss":"Issuer","aud":"Audience"}'.
Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:Information: Bearer was not authenticated. Failure message: IDX10503: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.RsaSecurityKey , KeyId:
'.
Exceptions caught:
'System.ObjectDisposedException: Safe handle has been closed
at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.Crypto.RsaVerify(Int32 type, Byte& m, Int32 m_len, Byte& sigbuf, Int32 siglen, SafeRsaHandle rsa)
at Interop.Crypto.RsaVerify(Int32 type, ReadOnlySpan`1 m, ReadOnlySpan`1 sigbuf, SafeRsaHandle rsa)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(ReadOnlySpan`1 hash, ReadOnlySpan`1 signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSAImplementation.RSAOpenSsl.VerifyHash(Byte[] hash, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Int32 offset, Int32 count, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at System.Security.Cryptography.RSA.VerifyData(Byte[] data, Byte[] signature, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding)
at Microsoft.IdentityModel.Tokens.AsymmetricSignatureProvider.Verify(Byte[] input, Byte[] signature)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(Byte[] encodedBytes, Byte[] signature, SecurityKey key, String algorithm, TokenValidationParameters validationParameters)
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)
'.
Here is a github repo with the problem: https://github.com/hasan-hasanov/AuthIssue
Is there anything that I am doing incorrectly? Any help is greatly appreciated.
Copied from original issue: dotnet/corefx#31762
Issue Analytics
- State:
- Created 5 years ago
- Comments:14 (11 by maintainers)
Top GitHub Comments
@bartonjs @hasan-hasanov closing this here. We need a bug against the appropriate project.
We might have accidentally introduced an error where post-dispose is the same as freshly created, where it thinks it needs to just make up a key on first (next, in this case) use.