dvsekhvalnov / jose-jwt

Ultimate Javascript Object Signing and Encryption (JOSE), JSON Web Token (JWT) and Json Web Keys (JWK) Implementation for .NET and .NET Core
MIT License
921 stars 183 forks source link

Access Denied - Encoding and Decoding using same certificate #209

Closed weirdyang closed 1 year ago

weirdyang commented 1 year ago

Hi,

I'm trying to encode and decode a JWT using the same certificate, but am getting this error during decoding:

Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException : Access denied.

What is causing this error?

Here's my code

             var x509cert = new X509Certificate2(certificate.Content, _password, X509KeyStorageFlags.Exportable);
            var payload = new Dictionary<string, object>()
            {
                { "sub", "mr.x@contoso.com" },
                { "exp", DateTimeOffset.Now.AddDays(5).ToUnixTimeSeconds() }
            };
            var encrypt = EncryptData(payload, x509cert);
            var certificate2 = _provider.GetService<AuditableRpDbContext>().Certificate
              .AsNoTracking()
              .FirstOrDefault(a => a.Type == cert2);

            var decrypt = DecryptKey(encrypt, x509cert);
            Assert.AreEqual(encrypt, decrypt);
        }

        private string EncryptData(Dictionary<string, object> strText, X509Certificate2 X509)
        {
            try
            {
                var rsa = X509.GetRSAPublicKey();
                var data = JWT.Encode(strText, rsa, JweAlgorithm.RSA_OAEP_256, JweEncryption.A256CBC_HS512);

                return data;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        private string DecryptKey(string strText, X509Certificate2 X509)
        {
            try
            {
                var rsa = X509.GetRSAPrivateKey();
                var data = JWT.Decode(strText, rsa, JweAlgorithm.RSA_OAEP_256, JweEncryption.A256CBC_HS512);

                return data;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
dvsekhvalnov commented 1 year ago

HI @weirdyang

are you getting it on Azure? Or locally on your dev machine?

weirdyang commented 1 year ago

Locally on my dev machine. When I switch it to X509KeyStorageFlags.EphemeralKeySet, it works. Does that mean I need to install the certs on the machine that is going to do the decryption?

dvsekhvalnov commented 1 year ago

https://github.com/dotnet/runtime/issues/19774#issuecomment-295366419 is it shedding some light on root cause?

You can try to use JWK to distribute keys, though it sill using same low level machinery under the hood, but may work probably.

weirdyang commented 1 year ago

Thanks! No wonder it works on the linux vm when deployed.