JonPSmith / AuthPermissions.AspNetCore

This library provides extra authorization and multi-tenant features to an ASP.NET Core application.
https://www.thereformedprogrammer.net/finally-a-library-that-improves-role-authorization-in-asp-net-core/
MIT License
764 stars 155 forks source link

SigningKey Property on AuthPJwtConfiguration doesn't support keys generated as byte[] #81

Closed pyrostew closed 1 year ago

pyrostew commented 1 year ago

In my project I have a requirement to use token signing keys that have either been generated per instance of the web server or by loading a key from a certificate. Both of these scenarios produce a key that is stored in a byte[].

I have had issue encoding that byte[] into a string in a useable way, the resulting key in the token builder doesn't match the original byte[] given to the token validation parameters.

Based on the examples and the documentation I understand the intention is to load a key from a file or some sort of secrets store, and that the key is some sort of human readable string. This doesn't work when using keys generated from crypto classes like System.Security.Cryptography.Aes which produce bytes that don't encode into strings in a reversible way.

My suggestion for resolving this which wouldn't break the current API would be to add a "SigningKeyRaw" property of type byte[] to the AuthPJwtConfiguration class. This property can be used directly by the token builder and the current "SigningKey" property can be updated to encode and decode to the new property.

I can raise a PR with this change if that is convenient.

JonPSmith commented 1 year ago

So you are saying that that the JWT token only supports ASCII characters. Can't you encode/decode your Unicode chars to ASCII characters?

pyrostew commented 1 year ago

The problem is the key for signing and validating the token. if you use a key that only has ASCII characters in it then all is fine because you can reversibly encode between a string and a byte[]. However if you are starting with a byte array that has been generated by a cryptographic algorithm you get bytes that aren't encoded into an ASCII string and therefore not reversible to the original byte[].

JonPSmith commented 1 year ago

Of course you can:

pyrostew commented 1 year ago

Those Methods are not reversible when you provide a a completely random byte[]. Using the following to create a key

PS C:\Users\Pyros> $keygen = [System.Security.Cryptography.AesManaged]::Create()
PS C:\Users\Pyros> $keygen.GenerateKey()
PS C:\Users\Pyros> $keygen.Key
188
12
225
208
221
196
251
128
164
82
160
192
154
131
137
86
223
171
123
38
2
81
70
207
144
205
133
114
45
72
218
71

Feeding that key into any of the following method calls produces a string that is not equivalent to the input byte[].

PS C:\Users\Pyros> [System.Text.Encoding]::ASCII.GetBytes([System.Text.Encoding]::ASCII.GetString($keygen.Key))
63
12
63
63
63
63
63
63
63
82
63
63
63
63
63
86
63
63
123
38
2
81
70
63
63
63
63
114
45
72
63
71
PS C:\Users\Pyros> [System.Text.Encoding]::ASCII.GetBytes([System.Text.Encoding]::UTF8.GetString($keygen.Key))
63
12
63
63
63
63
63
63
63
82
63
63
63
63
63
86
63
123
38
2
81
70
63
63
114
45
72
63
71
PS C:\Users\Pyros> [System.Text.Encoding]::UTF8.GetBytes([System.Text.Encoding]::UTF8.GetString($keygen.Key))
239
191
189
12
239
191
189
239
191
189
239
191
189
239
191
189
239
191
189
239
191
189
239
191
189
82
239
191
189
239
191
189
239
191
189
239
191
189
239
191
189
86
223
171
123
38
2
81
70
207
144
205
133
114
45
72
239
191
189
71

Therefore requiring providing a string for the signing key does not allow for using keys that have been generated from the crypto classes in .NET and for that matter keys from certificates.