alphagov / notifications-net-client

.NET client for the GOV.UK Notify API
https://www.nuget.org/packages/GovukNotify/
MIT License
25 stars 20 forks source link

HMACSHA256Algorithm is obsolete #172

Closed MichaelStevenson2207 closed 1 year ago

MichaelStevenson2207 commented 1 year ago

HMACSHA256Algorithm is obsolete: 'HMAC SHA based algorithms are not secure to protect modern web applications. Consider switching to RSASSA or ECDSA:

    public static string CreateToken(string secret, string serviceId)
    {
        ValidateGuids(new [] { secret, serviceId });

        var payload = new Dictionary<string, object>
        {
            { "iss", serviceId },
            { "iat", GetCurrentTimeAsSeconds() }
        };

        IJwtAlgorithm algorithm = new HMACSHA256Algorithm();

        IJsonSerializer serializer = new JsonNetSerializer();
        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
        IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

        var notifyToken = encoder.Encode(payload, secret);

        return notifyToken;
    }
leohemsted commented 1 year ago

Hi @MichaelStevenson2207, thanks for your suggestion!

Unfortunately, we won't be able to implement this, at least not any time soon. Currently, when we verify the JWT token in an API request, we create our own signature for the JWT payload using the secret we have stored in our systems for your api key, and then compare signatures against the one you sent over. Both RSASSA and ECDSA operate on a public-private key pair, which would require significant changes in how users authenticate with us, how we store our API keys, and what the format of the API keys looks like, and is not a change we can make lightly or quickly.

I also think it's a bit unfair to say that HMAC is not secure. It's not as secure as keypairs perhaps, but has a variety of advantages over them. HMAC is still a secure cryptographic hash, in that someone who does not know your secret cannot reverse engineer the digital signature attached to your JWT tokens to create their own malicious token impersonating you.

Keypairs are better when there are multiple verifying parties (for example with a single sign-on system where you might have multiple services all verifying the same JWT), however, the only verifying party is GOV.UK Notify itself, so this isn't a concern for our particular use case.

HMAC SHA based algorithms are also significantly more performant, which is absolutely a concern when dealing with volumes at scale, so we would not be able to simply switch over or support RSA without plenty of thoughtful testing.

Nevertheless, thank you for your suggestion! We may end up changing how we authenticate in the future anyway, and I've had fun reading up on digital signing and the alternatives to HMAC.

Thanks,

Leo