Пример #1
0
        public void Build_Jws()
        {
            var builder = new JwtDescriptorBuilder();

            var now = EpochTime.ToDateTime(EpochTime.UtcNow);

            builder
            .SignWith(RsaJwk.GenerateKey(2048, true, SignatureAlgorithm.RsaSsaPssSha256))
            .IssuedBy("https://issuer.example.com")
            .ExpiresAt(now);

            var descriptor = builder.Build();

            Assert.IsType <JwsDescriptor>(descriptor);
            var jws = (JwsDescriptor)descriptor;

            Assert.Equal("https://issuer.example.com", jws.Issuer);
            Assert.Equal(now, jws.ExpirationTime);
            Assert.Null(jws.JwtId);
            Assert.Null(jws.IssuedAt);
            Assert.Null(jws.NotBefore);
            Assert.Null(jws.Subject);
            Assert.Null(jws.KeyId);
            Assert.Null(jws.Audience);
            Assert.Equal(SignatureAlgorithm.RsaSsaPssSha256, jws.Algorithm);
        }
Пример #2
0
        public RsaKeyWrapper(RsaJwk key, EncryptionAlgorithm encryptionAlgorithm, KeyManagementAlgorithm algorithm)
            : base(encryptionAlgorithm, algorithm)
        {
            Debug.Assert(key.SupportKeyManagement(algorithm));
            Debug.Assert(algorithm.Category == AlgorithmCategory.Rsa);
            _key = key;
#if SUPPORT_SPAN_CRYPTO
            _rsa = RSA.Create(key.ExportParameters());
#else
#if NET461 || NET47
            _rsa = new RSACng();
#else
            _rsa = RSA.Create();
#endif
            _rsa.ImportParameters(key.ExportParameters());
#endif
            _padding = algorithm.Id switch
            {
                AlgorithmId.RsaOaep => RSAEncryptionPadding.OaepSHA1,
                AlgorithmId.Rsa1_5 => RSAEncryptionPadding.Pkcs1,
                AlgorithmId.RsaOaep256 => RSAEncryptionPadding.OaepSHA256,
                AlgorithmId.RsaOaep384 => RSAEncryptionPadding.OaepSHA384,
                AlgorithmId.RsaOaep512 => RSAEncryptionPadding.OaepSHA512,
                _ => throw ThrowHelper.CreateNotSupportedException_AlgorithmForKeyWrap(algorithm)
            };
        }
Пример #3
0
        private static void GenerateKeys()
        {
            // The GenerateKey method creates a new crypto-random asymmetric key for elliptic curve algorithms
            var ecKey = ECJwk.GenerateKey(EllipticalCurve.P521, withPrivateKey: true, SignatureAlgorithm.EcdsaSha512);

            ecKey.Kid = "Generated-ES512";
            Console.WriteLine("Asymmetric generated JWK for elliptic curve P-521, for ES512 signature algorithm:");
            Console.WriteLine(ecKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random asymmetric key for RSA algorithms
            var rsaKey = RsaJwk.GenerateKey(2048, withPrivateKey: true, SignatureAlgorithm.RsaSsaPssSha384);

            rsaKey.Kid = "Generated-PS384";
            Console.WriteLine("Asymmetric generated JWK of 2048 bits for RSA, for PS384 signature algorithm:");
            Console.WriteLine(rsaKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random symmetric key for symmetric algorithms
            var symmetricKey = SymmetricJwk.GenerateKey(128, SignatureAlgorithm.HmacSha256);

            symmetricKey.Kid = "Generated-HS256";
            Console.WriteLine("Symmetric generated JWK of 128 bits, for HS256 signature algorithm:");
            Console.WriteLine(symmetricKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random aymmetric key for RSA algorithms
            var symmetricKey2 = SymmetricJwk.GenerateKey(256);

            Console.WriteLine("Symmetric generated JWK of 256 bits, without specified signature algorithm, without key identifier:");
            Console.WriteLine(symmetricKey2);
            Console.WriteLine();
        }
Пример #4
0
        public void Read()
        {
            var key = new RsaJwk
                      (
                n: "w7Zdfmece8iaB0kiTY8pCtiBtzbptJmP28nSWwtdjRu0f2GFpajvWE4VhfJAjEsOcwYzay7XGN0b-X84BfC8hmCTOj2b2eHT7NsZegFPKRUQzJ9wW8ipn_aDJWMGDuB1XyqT1E7DYqjUCEOD1b4FLpy_xPn6oV_TYOfQ9fZdbE5HGxJUzekuGcOKqOQ8M7wfYHhHHLxGpQVgL0apWuP2gDDOdTtpuld4D2LK1MZK99s9gaSjRHE8JDb1Z4IGhEcEyzkxswVdPndUWzfvWBBWXWxtSUvQGBRkuy1BHOa4sP6FKjWEeeF7gm7UMs2Nm2QUgNZw6xvEDGaLk4KASdIxRQ",
                e: "AQAB"
                      )
            {
                Kid = "1e9gdk7",
                Alg = SignatureAlgorithm.RsaSha256.Utf8Name
            };
            var reader = new JwtReader();

            var policy = new TokenValidationPolicyBuilder()
                         .RequireSignature(key)
                         .Build();

            var result = reader.TryReadToken("eyJraWQiOiIxZTlnZGs3IiwiYWxnIjoiUlMyNTYifQ.ewogImlzcyI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZfV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5NzAsCiAibmFtZSI6ICJKYW5lIERvZSIsCiAiZ2l2ZW5fbmFtZSI6ICJKYW5lIiwKICJmYW1pbHlfbmFtZSI6ICJEb2UiLAogImdlbmRlciI6ICJmZW1hbGUiLAogImJpcnRoZGF0ZSI6ICIwMDAwLTEwLTMxIiwKICJlbWFpbCI6ICJqYW5lZG9lQGV4YW1wbGUuY29tIiwKICJwaWN0dXJlIjogImh0dHA6Ly9leGFtcGxlLmNvbS9qYW5lZG9lL21lLmpwZyIKfQ.rHQjEmBqn9Jre0OLykYNnspA10Qql2rvx4FsD00jwlB0Sym4NzpgvPKsDjn_wMkHxcp6CilPcoKrWHcipR2iAjzLvDNAReF97zoJqq880ZD1bwY82JDauCXELVR9O6_B0w3K-E7yM2macAAgNCUwtik6SjoSUZRcf-O5lygIyLENx882p6MtmwaL1hd6qn5RZOQ0TLrOYu0532g9Exxcm-ChymrB4xLykpDj3lUivJt63eEGGN6DH5K6o33TcxkIjNrCD4XB1CKKumZvCedgHHF3IAK4dVEDSUoGlH9z4pP_eWYNXvqQOjGs-rDaQzUHl6cQQWNiDpWOl_lxXjQEvQ", policy);
            var token  = result.Token.AsIdToken();

            Assert.Equal("http://server.example.com", token.Issuer);
            Assert.Equal("248289761001", token.Subject);
            Assert.Equal("s6BhdRkqt3", token.Audiences.FirstOrDefault());
            Assert.Equal("n-0S6_WzA2Mj", token.Nonce);
            Assert.Equal(EpochTime.ToDateTime(1311281970), token.ExpirationTime);
            Assert.Equal(EpochTime.ToDateTime(1311280970), token.IssuedAt);
            Assert.Equal("Jane Doe", token.Payload["name"]);
            Assert.Equal("Jane", token.GivenName);
            Assert.Equal("Doe", token.FamilyName);
            Assert.Equal("female", token.Gender);
            Assert.Equal("0000-10-31", token.Birthdate);
            Assert.Equal("*****@*****.**", token.Email);
            Assert.Equal("http://example.com/janedoe/me.jpg", token.Picture);
        }
Пример #5
0
        private static void GenerateKeys()
        {
            // The GenerateKey method creates a new crypto-random asymmetric key for elliptic curve algorithms
            var ecKey = ECJwk.GeneratePrivateKey(SignatureAlgorithm.ES512);

            Console.WriteLine("Asymmetric generated JWK for elliptic curve P-521, for ES512 signature algorithm:");
            Console.WriteLine(ecKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random asymmetric key for RSA algorithms
            // You may specify a bigger key size. The default is the minimum size (2048 bits for RSA)
            var rsaKey = RsaJwk.GeneratePrivateKey(SignatureAlgorithm.PS384);

            Console.WriteLine("Asymmetric generated JWK of 2048 bits for RSA, for PS384 signature algorithm:");
            Console.WriteLine(rsaKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random symmetric key for symmetric algorithms
            var symmetricKey = SymmetricJwk.GenerateKey(SignatureAlgorithm.HS256);

            Console.WriteLine("Symmetric generated JWK of 128 bits, for HS256 signature algorithm:");
            Console.WriteLine(symmetricKey);
            Console.WriteLine();

            // The GenerateKey method creates a new crypto-random aymmetric key for RSA algorithms
            var symmetricKey2 = SymmetricJwk.GenerateKey(256, computeThumbprint: false);

            Console.WriteLine("Symmetric generated JWK of 256 bits, without specified signature algorithm, without key identifier (the thumbprint):");
            Console.WriteLine(symmetricKey2);
            Console.WriteLine();
        }
Пример #6
0
        public void FromPem_PublicKey(string pem)
        {
            var key = RsaJwk.FromPem(pem);

            AssertKeyEquals(ToPublic(DiminishedDPParameters), key.ExportParameters());
            Assert.False(key.HasPrivateKey);
        }
Пример #7
0
        // SEQUENCE
        //   INTEGER 0 version
        //   SEQUENCE
        //     OBJECT IDENTIFIER 1.2.840.113549.1.1.1
        //     NULL
        //   OCTET STRING
        //     SEQUENCE
        //       INTEGER 0
        //       INTEGER N
        //       INTEGER E
        //       INTEGER D
        //       INTEGER P
        //       INTEGER Q
        //       INTEGER DP
        //       INTEGER DQ
        //       INTEGER QI
        private static RsaJwk ReadRsaPrivateKey(ref AsnReader reader)
        {
            reader = reader.ReadOctetString();
            reader = reader.ReadSequence();
            var version = reader.ReadInteger();

            if (version.Length != 1 || version[0] != 0)
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            var n  = reader.ReadInteger();
            var e  = reader.ReadInteger();
            var d  = reader.ReadInteger();
            var p  = reader.ReadInteger();
            var q  = reader.ReadInteger();
            var dp = reader.ReadInteger();
            var dq = reader.ReadInteger();
            var qi = reader.ReadInteger();

            if (reader.Read())
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            return(RsaJwk.FromByteArray(
                       n: AsnReader.TrimLeadingZeroes(n),
                       e: AsnReader.TrimLeadingZeroes(e, align: false),
                       d: AsnReader.TrimLeadingZeroes(d),
                       p: AsnReader.TrimLeadingZeroes(p),
                       q: AsnReader.TrimLeadingZeroes(q),
                       dp: AsnReader.TrimLeadingZeroes(dp),
                       dq: AsnReader.TrimLeadingZeroes(dq),
                       qi: AsnReader.TrimLeadingZeroes(qi)));
        }
        private static JwsDescriptorWrapper CreateDescriptor(SignatureAlgorithm algorithm)
        {
            var jwk = algorithm.Category switch
            {
                Cryptography.AlgorithmCategory.None => Jwk.None,
                Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(algorithm),
                Cryptography.AlgorithmCategory.Rsa => RsaJwk.GeneratePrivateKey(4096, algorithm),
                Cryptography.AlgorithmCategory.Aes => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.AesGcm => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Hmac => SymmetricJwk.GenerateKey(algorithm),
                _ => throw new InvalidOperationException()
            };

            var descriptor = new JwsDescriptor(jwk, algorithm)
            {
                Payload = new JwtPayload
                {
                    { JwtClaimNames.Iat, EpochTime.UtcNow },
                    { JwtClaimNames.Exp, EpochTime.UtcNow + EpochTime.OneHour },
                    { JwtClaimNames.Iss, "https://idp.example.com/" },
                    { JwtClaimNames.Aud, "636C69656E745F6964" }
                }
            };

            return(new JwsDescriptorWrapper(descriptor));
        }
    }
Пример #9
0
        public void Equal()
        {
            var key = RsaJwk.GeneratePrivateKey(4096);

            Assert.True(key.Equals(key));
            Assert.Equal(key, key);
            var publicKey = key.AsPublicKey();

            Assert.NotEqual(key, publicKey);
            var copiedKey = Jwk.FromJson(key.ToString());

            Assert.Equal(key, copiedKey);

            // 'kid' is not a discriminant, excepted if the value is different.
            copiedKey.Kid = default;
            Assert.Equal(key, copiedKey);
            Assert.Equal(copiedKey, key);
            key.Kid = default;
            Assert.Equal(key, copiedKey);
            key.Kid       = JsonEncodedText.Encode("X");
            copiedKey.Kid = JsonEncodedText.Encode("Y");
            Assert.NotEqual(key, copiedKey);

            Assert.NotEqual(key, Jwk.None);
        }
Пример #10
0
        // SEQUENCE
        //   INTEGER N
        //   INTEGER E
        public static RsaJwk ReadRsaPublicKey(ReadOnlySpan <char> key)
        {
            var data = key.Slice(PublicRsaKeyPrefix.Length, key.Length - PublicRsaKeyPrefix.Length - PublicRsaKeySuffix.Length);

            byte[]      tmpArray;
            Span <byte> keyData = tmpArray = ArrayPool <byte> .Shared.Rent(Base64.GetArraySizeRequiredToDecode(data.Length));

            try
            {
                int length = Base64.Decode(data, keyData);
                var reader = new AsnReader(keyData.Slice(0, length));

                reader = reader.ReadSequence();
                var n = reader.ReadInteger();
                var e = reader.ReadInteger();
                if (reader.Read())
                {
                    ThrowHelper.ThrowInvalidOperationException_InvalidPem();
                }

                return(RsaJwk.FromByteArray(
                           n: AsnReader.TrimLeadingZeroes(n),
                           e: AsnReader.TrimLeadingZeroes(e, align: false)));
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(tmpArray);
            }
        }
Пример #11
0
        public void Build_Jws_AutomaticClaims()
        {
            var builder = new JwtDescriptorBuilder();

            var now = EpochTime.ToDateTime(EpochTime.UtcNow);

            builder
            .SignWith(RsaJwk.GenerateKey(2048, true, SignatureAlgorithm.RsaSsaPssSha256))
            .ExpiresAfter(10)
            .NotBefore(5)
            .WithAutomaticId()
            .WithAutomaticIssuedAt();

            var descriptor = builder.Build();

            Assert.IsType <JwsDescriptor>(descriptor);
            var jws = (JwsDescriptor)descriptor;

            Assert.NotNull(jws.ExpirationTime);
            Assert.InRange((jws.ExpirationTime - now).Value.TotalSeconds - 10, -2, 2);
            Assert.NotNull(jws.JwtId);
            Assert.NotNull(jws.IssuedAt);
            Assert.InRange((jws.IssuedAt - now).Value.TotalSeconds, -2, 2);
            Assert.NotNull(jws.NotBefore);
            Assert.InRange((jws.NotBefore - now).Value.TotalSeconds - 5, -2, 2);
            Assert.Null(jws.Subject);
            Assert.Null(jws.KeyId);
            Assert.Null(jws.Audience);
            Assert.Equal(SignatureAlgorithm.RsaSsaPssSha256, jws.Algorithm);
        }
Пример #12
0
        private Jwk TryWrapKey_Success(SymmetricJwk keyToWrap, EncryptionAlgorithm enc, KeyManagementAlgorithm alg)
        {
            var keyEncryptionKey = RsaJwk.GeneratePrivateKey(alg.RequiredKeySizeInBits);
            var wrapper          = new RsaKeyWrapper(keyEncryptionKey, enc, alg);
            var cek = WrapKey(wrapper, keyToWrap, out var header);

            Assert.Equal(0, header.Count);
            return(cek);
        }
Пример #13
0
        public void FromPem_UnexpectedKeyType_ThrowArgumentException()
        {
            string pem = @"
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcKEsLbFoRe1W/2jP
whpHKz8E19aFG/Y0ny19WzRSs4qhRANCAASBAezkdGSm6tcM9ppuK9PYhpGjJi0i
y6T3Y16v8maAqNihK6YdWZI19n2ctNWPF4PTykPnjwpauqYkB5k2wMOp
-----END PRIVATE KEY-----";

            Assert.Throws <InvalidOperationException>(() => RsaJwk.FromPem(pem));
        }
Пример #14
0
        public void WrapKey_Failure()
        {
            var keyEncryptionKey = RsaJwk.GenerateKey(2048, true);
            var wrapper          = new RsaKeyWrapper(keyEncryptionKey, EncryptionAlgorithm.Aes256CbcHmacSha512, KeyManagementAlgorithm.RsaOaep);
            var destination      = new byte[0];
            var header           = new JwtObject();

            Assert.Throws <CryptographicException>(() => wrapper.WrapKey(null, header, destination));
            wrapper.Dispose();
            Assert.Throws <ObjectDisposedException>(() => wrapper.WrapKey(null, header, destination));

            Assert.Equal(0, header.Count);
        }
Пример #15
0
        public override void Canonicalize()
        {
            var jwk = RsaJwk.GeneratePrivateKey(2048, SignatureAlgorithm.RS256);
            var canonicalizedKey = (RsaJwk)CanonicalizeKey(jwk);

            Assert.False(canonicalizedKey.E.IsEmpty);
            Assert.False(canonicalizedKey.N.IsEmpty);

            Assert.True(canonicalizedKey.DP.IsEmpty);
            Assert.True(canonicalizedKey.DQ.IsEmpty);
            Assert.True(canonicalizedKey.D.IsEmpty);
            Assert.True(canonicalizedKey.P.IsEmpty);
            Assert.True(canonicalizedKey.Q.IsEmpty);
            Assert.True(canonicalizedKey.QI.IsEmpty);
        }
Пример #16
0
        // SEQUENCE
        //   SEQUENCE
        //     OBJECT IDENTIFIER 1.2.840.113549.1.1.1
        //     NULL
        //   BIT STRING
        //     SEQUENCE
        //       INTEGER N
        //       INTEGER E
        private static AsymmetricJwk ReadRsaPublicKey(ref AsnReader reader)
        {
            reader = reader.ReadBitString();
            reader = reader.ReadSequence();
            var n = reader.ReadInteger();
            var e = reader.ReadInteger();

            if (reader.Read())
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            return(RsaJwk.FromByteArray(
                       n: AsnReader.TrimLeadingZeroes(n),
                       e: AsnReader.TrimLeadingZeroes(e, align: false)));
        }
Пример #17
0
        public void Setup()
        {
            var key    = SymmetricJwk.GenerateKey(256);
            var rsaKey = RsaJwk.GeneratePrivateKey(2048);
            var ecKey  = ECJwk.GeneratePrivateKey(EllipticalCurve.P256);

            for (int i = 0; i < Count; i++)
            {
                key.TryGetSigner(SignatureAlgorithm.HS256, out var signer);
                id = i;
                _dictionary.Add(id, signer);
                _concurrentDictionary.TryAdd(id, signer);
                _cryptoStore.TryAdd(id, signer);
                _cryptoStore2.TryAdd(id, signer);
            }
        }
Пример #18
0
        public void Build_JweMissingKeyManagementAlgorithm()
        {
            var builder = new JwtDescriptorBuilder();

            var now = EpochTime.ToDateTime(EpochTime.UtcNow);

            builder
            .SignWith(RsaJwk.GenerateKey(2048, true, SignatureAlgorithm.RsaSsaPssSha256))
            .EncryptWith(SymmetricJwk.GenerateKey(128), EncryptionAlgorithm.Aes128CbcHmacSha256)
            .IssuedBy("https://issuer.example.com")
            .ExpiresAt(now);

            var exception = Assert.Throws <InvalidOperationException>(() => builder.Build());

            Assert.Contains("No algorithm is defined for the key management encryption.", exception.Message);
        }
Пример #19
0
        // SEQUENCE
        //   INTEGER 0
        //   INTEGER N
        //   INTEGER E
        //   INTEGER D
        //   INTEGER P
        //   INTEGER Q
        //   INTEGER DP
        //   INTEGER DQ
        //   INTEGER QI
        public static RsaJwk ReadRsaPrivateKey(ReadOnlySpan <char> key)
        {
            var data = key.Slice(PrivateRsaKeyPrefix.Length, key.Length - PrivateRsaKeyPrefix.Length - PrivatRsaKeySuffix.Length);

            byte[]      tmpArray;
            Span <byte> keyData = tmpArray = ArrayPool <byte> .Shared.Rent(Base64.GetArraySizeRequiredToDecode(data.Length));

            try
            {
                int length = Base64.Decode(data, keyData);
                var reader = new AsnReader(keyData.Slice(0, length));
                reader = reader.ReadSequence();
                var version = reader.ReadInteger();
                if (version.Length != 1 || version[0] != 0)
                {
                    ThrowHelper.ThrowInvalidOperationException_InvalidPem();
                }

                var n  = reader.ReadInteger();
                var e  = reader.ReadInteger();
                var d  = reader.ReadInteger();
                var p  = reader.ReadInteger();
                var q  = reader.ReadInteger();
                var dp = reader.ReadInteger();
                var dq = reader.ReadInteger();
                var qi = reader.ReadInteger();
                if (reader.Read())
                {
                    ThrowHelper.ThrowInvalidOperationException_InvalidPem();
                }

                return(RsaJwk.FromByteArray(
                           n: AsnReader.TrimLeadingZeroes(n),
                           e: AsnReader.TrimLeadingZeroes(e, align: false),
                           d: AsnReader.TrimLeadingZeroes(d),
                           p: AsnReader.TrimLeadingZeroes(p),
                           q: AsnReader.TrimLeadingZeroes(q),
                           dp: AsnReader.TrimLeadingZeroes(dp),
                           dq: AsnReader.TrimLeadingZeroes(dq),
                           qi: AsnReader.TrimLeadingZeroes(qi)));
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(tmpArray);
            }
        }
Пример #20
0
        public override void Canonicalize()
        {
            var jwk = RsaJwk.GenerateKey(2048, true);
            var canonicalizedKey = (RsaJwk)CanonicalizeKey(jwk);

            Assert.NotNull(canonicalizedKey.E);
            Assert.NotEmpty(canonicalizedKey.E);
            Assert.NotNull(canonicalizedKey.N);
            Assert.NotEmpty(canonicalizedKey.N);

            Assert.Null(canonicalizedKey.DP);
            Assert.Null(canonicalizedKey.DQ);
            Assert.Null(canonicalizedKey.D);
            Assert.Null(canonicalizedKey.P);
            Assert.Null(canonicalizedKey.Q);
            Assert.Null(canonicalizedKey.QI);
        }
Пример #21
0
        public void Thumbprint()
        {
            // https://tools.ietf.org/html/rfc7638#section-3.1
            var key = new RsaJwk
                      (
                e: "AQAB",
                n: "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"
                      )
            {
                Kid = "2011-04-29",
                Alg = ((SignatureAlgorithm)"RS256").Utf8Name
            };

            var thumbprint = key.ComputeThumbprint();

            Assert.Equal(Encoding.UTF8.GetBytes("NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs"), thumbprint);
        }
Пример #22
0
        public RsaKeyUnwrapper(RsaJwk key, EncryptionAlgorithm encryptionAlgorithm, KeyManagementAlgorithm algorithm)
            : base(encryptionAlgorithm, algorithm)
        {
            Debug.Assert(key.SupportKeyManagement(algorithm));
            Debug.Assert(algorithm.Category == AlgorithmCategory.Rsa);
#if SUPPORT_SPAN_CRYPTO
            _rsa = RSA.Create(key.ExportParameters());
#else
#if NET461 || NET47
            _rsa = new RSACng();
#else
            _rsa = RSA.Create();
#endif
            _rsa.ImportParameters(key.ExportParameters());
#endif
            _padding = RsaHelper.GetEncryptionPadding(algorithm.Id);
        }
Пример #23
0
        public RsaSignatureVerifier(RsaJwk key, SignatureAlgorithm algorithm)
            : base(algorithm)
        {
            Debug.Assert(key != null);
            Debug.Assert(key.SupportSignature(algorithm));

            if (key.KeySizeInBits < 1024)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException_SigningKeyTooSmall(key, 1024);
            }

            _hashAlgorithm    = algorithm.HashAlgorithm;
            _sha              = algorithm.Sha;
            _signaturePadding = RsaHelper.GetPadding(algorithm);

            _hashSizeInBytes       = key.KeySizeInBits >> 3;
            _base64HashSizeInBytes = Base64Url.GetArraySizeRequiredToEncode(_hashSizeInBytes);
            _rsaPool = new ObjectPool <RSA>(new RsaObjectPoolPolicy(key.ExportParameters()));
        }
Пример #24
0
        private async Task <Jwk[]> GetKeysAsync()
        {
            var keys = new List <Jwk>();

            await foreach (var keyProperties in _client.GetPropertiesOfKeysAsync())
            {
                var kvKey = await _client.GetKeyAsync(keyProperties.Name);

                Jwk?key = null;
                if (kvKey.Value.KeyType == KeyType.Oct)
                {
                    key = SymmetricJwk.FromByteArray(kvKey.Value.Key.K, false);
                }
                else if (kvKey.Value.KeyType == KeyType.Rsa || kvKey.Value.KeyType == KeyType.RsaHsm)
                {
                    key = RsaJwk.FromParameters(kvKey.Value.Key.ToRSA(true).ExportParameters(true), false);
                }
#if !NETFRAMEWORK
                else if (kvKey.Value.KeyType == KeyType.Ec || kvKey.Value.KeyType == KeyType.EcHsm)
                {
                    ECJwk.FromParameters(ConvertToECParameters(kvKey.Value), computeThumbprint: false);
                }
#endif

                if (!(key is null))
                {
                    key.Kid = JsonEncodedText.Encode(kvKey.Value.Key.Id);
                    if (kvKey.Value.Key.KeyOps != null)
                    {
                        foreach (var operation in kvKey.Value.Key.KeyOps)
                        {
                            key.KeyOps.Add(JsonEncodedText.Encode(operation.ToString()));
                        }
                    }

                    keys.Add(key);
                }
            }

            return(keys.ToArray());
        }
Пример #25
0
        public override void WriteTo()
        {
            var key = RsaJwk.GenerateKey(2048, true, SignatureAlgorithm.RsaSha256.Utf8Name);

            key.Kid = "kid-rsa";
            key.KeyOps.Add("sign");
            key.Use     = JwkUseNames.Sig.ToArray();
            key.X5t     = Base64Url.Decode("dGhpcyBpcyBhIFNIQTEgdGVzdCE");
            key.X5tS256 = Base64Url.Decode("dGhpcyBpcyBhIFNIQTI1NiB0ZXN0ISAgICAgICAgICAgIA");
            key.X5u     = "https://example.com";
            key.X5c.Add(Convert.FromBase64String("MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA=="));

            using (var bufferWriter = new PooledByteBufferWriter())
            {
                key.Serialize(bufferWriter);
                var json = Encoding.UTF8.GetString(bufferWriter.WrittenSpan.ToArray());

                Assert.Contains("\"kid\":\"kid-rsa\"", json);
                Assert.Contains("\"key_ops\":[\"sign\"]", json);
                Assert.Contains("\"use\":\"sig\"", json);
                Assert.Contains("\"x5t\":\"dGhpcyBpcyBhIFNIQTEgdGVzdCE\"", json);
                Assert.Contains("\"x5t#S256\":\"dGhpcyBpcyBhIFNIQTI1NiB0ZXN0ISAgICAgICAgICAgIA\"", json);
#if NETCOREAPP
                Assert.Contains("\"x5u\":\"" + JsonEncodedText.Encode("https://example.com", Constants.JsonEncoder) + "\"", json);
                Assert.Contains("\"x5c\":[\"" + JsonEncodedText.Encode("MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA==", Constants.JsonEncoder) + "\"]", json);
#else
                Assert.Contains("\"x5u\":\"" + JsonEncodedText.Encode("https://example.com") + "\"", json);
                Assert.Contains("\"x5c\":[\"" + JsonEncodedText.Encode("MIIDQjCCAiqgAwIBAgIGATz/FuLiMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDAeFw0xMzAyMjEyMzI5MTVaFw0xODA4MTQyMjI5MTVaMGIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDTzEPMA0GA1UEBxMGRGVudmVyMRwwGgYDVQQKExNQaW5nIElkZW50aXR5IENvcnAuMRcwFQYDVQQDEw5CcmlhbiBDYW1wYmVsbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64zn8/QnHYMeZ0LncoXaEde1fiLm1jHjmQsF/449IYALM9if6amFtPDy2yvz3YlRij66s5gyLCyO7ANuVRJx1NbgizcAblIgjtdf/u3WG7K+IiZhtELto/A7Fck9Ws6SQvzRvOE8uSirYbgmj6He4iO8NCyvaK0jIQRMMGQwsU1quGmFgHIXPLfnpnfajr1rVTAwtgV5LEZ4Iel+W1GC8ugMhyr4/p1MtcIM42EA8BzE6ZQqC7VPqPvEjZ2dbZkaBhPbiZAS3YeYBRDWm1p1OZtWamT3cEvqqPpnjL1XyW+oyVVkaZdklLQp2Btgt9qr21m42f4wTw+Xrp6rCKNb0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAh8zGlfSlcI0o3rYDPBB07aXNswb4ECNIKG0CETTUxmXl9KUL+9gGlqCz5iWLOgWsnrcKcY0vXPG9J1r9AqBNTqNgHq2G03X09266X5CpOe1zFo+Owb1zxtp3PehFdfQJ610CDLEaS9V9Rqp17hCyybEpOGVwe8fnk+fbEL2Bo3UPGrpsHzUoaGpDftmWssZkhpBJKVMJyf/RuP2SmmaIzmnw9JiSlYhzo4tpzd5rFXhjRbg4zW9C+2qok+2+qDM1iJ684gPHMIY8aLWrdgQTxkumGmTqgawR+N5MDtdPTEQ0XfIBc2cJEUyMTY5MPvACWpkA6SdS4xSvdXK3IVfOWA==") + "\"]", json);
#endif

                Assert.Contains("\"e\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.E)) + "\"", json);
                Assert.Contains("\"n\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.N)) + "\"", json);
                Assert.Contains("\"d\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.D)) + "\"", json);

                Assert.Contains("\"dp\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.DP)) + "\"", json);
                Assert.Contains("\"dq\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.DQ)) + "\"", json);
                Assert.Contains("\"p\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.P)) + "\"", json);
                Assert.Contains("\"q\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.Q)) + "\"", json);
                Assert.Contains("\"qi\":\"" + Encoding.UTF8.GetString(Base64Url.Encode(key.QI)) + "\"", json);
            }
        }
Пример #26
0
        // SEQUENCE
        //   INTEGER N
        //   INTEGER E
        public static RsaJwk ReadRsaPublicKey(string key)
        {
            string base64KeyData = key.Substring(PublicRsaKeyPrefix.Length, key.Length - PublicRsaKeyPrefix.Length - PublicRsaKeySuffix.Length);

            byte[] keyData = Convert.FromBase64String(base64KeyData);

            var reader = new AsnReader(keyData);

            reader = reader.ReadSequence();
            var n = reader.ReadInteger();
            var e = reader.ReadInteger();

            if (reader.Read())
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            return(RsaJwk.FromByteArray(
                       n: AsnReader.TrimLeadingZeroes(n),
                       e: AsnReader.TrimLeadingZeroes(e, align: false)));
        }
Пример #27
0
        public void Write_Binary()
        {
            var data = new byte[256];

            FillData(data);
            var key = new RsaJwk
                      (
                n: "sXchDaQebHnPiGvyDOAT4saGEUetSyo9MKLOoWFsueri23bOdgWp4Dy1WlUzewbgBHod5pcM9H95GQRV3JDXboIRROSBigeC5yjU1hGzHHyXss8UDprecbAYxknTcQkhslANGRUZmdTOQ5qTRsLAt6BTYuyvVRdhS8exSZEy_c4gs_7svlJJQ4H9_NxsiIoLwAEk7-Q3UXERGYw_75IDrGA84-lA_-Ct4eTlXHBIY2EaV7t7LjJaynVJCpkv4LKjTTAumiGUIuQhrNhZLuF_RJLqHpM2kgWFLU7-VTdL1VbC2tejvcI2BlMkEpk1BzBZI0KQB0GaDWFLN-aEAw3vRw",
                e: "AQAB",
                d: "VFCWOqXr8nvZNyaaJLXdnNPXZKRaWCjkU5Q2egQQpTBMwhprMzWzpR8Sxq1OPThh_J6MUD8Z35wky9b8eEO0pwNS8xlh1lOFRRBoNqDIKVOku0aZb-rynq8cxjDTLZQ6Fz7jSjR1Klop-YKaUHc9GsEofQqYruPhzSA-QgajZGPbE_0ZaVDJHfyd7UUBUKunFMScbflYAAOYJqVIVwaYR5zWEEceUjNnTNo_CVSj-VvXLO5VZfCUAVLgW4dpf1SrtZjSt34YLsRarSb127reG_DUwg9Ch-KyvjT1SkHgUWRVGcyly7uvVGRSDwsXypdrNinPA4jlhoNdizK2zF2CWQ",
                p: "9gY2w6I6S6L0juEKsbeDAwpd9WMfgqFoeA9vEyEUuk4kLwBKcoe1x4HG68ik918hdDSE9vDQSccA3xXHOAFOPJ8R9EeIAbTi1VwBYnbTp87X-xcPWlEPkrdoUKW60tgs1aNd_Nnc9LEVVPMS390zbFxt8TN_biaBgelNgbC95sM",
                q: "uKlCKvKv_ZJMVcdIs5vVSU_6cPtYI1ljWytExV_skstvRSNi9r66jdd9-yBhVfuG4shsp2j7rGnIio901RBeHo6TPKWVVykPu1iYhQXw1jIABfw-MVsN-3bQ76WLdt2SDxsHs7q7zPyUyHXmps7ycZ5c72wGkUwNOjYelmkiNS0",
                dp: "w0kZbV63cVRvVX6yk3C8cMxo2qCM4Y8nsq1lmMSYhG4EcL6FWbX5h9yuvngs4iLEFk6eALoUS4vIWEwcL4txw9LsWH_zKI-hwoReoP77cOdSL4AVcraHawlkpyd2TWjE5evgbhWtOxnZee3cXJBkAi64Ik6jZxbvk-RR3pEhnCs",
                dq: "o_8V14SezckO6CNLKs_btPdFiO9_kC1DsuUTd2LAfIIVeMZ7jn1Gus_Ff7B7IVx3p5KuBGOVF8L-qifLb6nQnLysgHDh132NDioZkhH7mI7hPG-PYE_odApKdnqECHWw0J-F0JWnUd6D2B_1TvF9mXA2Qx-iGYn8OVV1Bsmp6qU",
                qi: "eNho5yRBEBxhGBtQRww9QirZsB66TrfFReG_CcteI1aCneT0ELGhYlRlCtUkTRclIfuEPmNsNDPbLoLqqCVznFbvdB7x-Tl-m0l_eFTj2KiqwGqE9PZB9nNTwMVvH3VRRSLWACvPnSiwP8N5Usy-WRXS-V7TbpxIhvepTfE0NNo"
                      )
            {
                Alg = KeyManagementAlgorithm.RsaPkcs1.Utf8Name
            };

            var descriptor = new BinaryJweDescriptor(data);

            descriptor.EncryptionKey       = key;
            descriptor.EncryptionAlgorithm = EncryptionAlgorithm.Aes128CbcHmacSha256;
            descriptor.Algorithm           = KeyManagementAlgorithm.RsaPkcs1;

            JwtWriter writer = new JwtWriter();
            var       value  = writer.WriteToken(descriptor);

            Assert.NotNull(value);

            var reader = new JwtReader(key);
            var result = reader.TryReadToken(value, TokenValidationPolicy.NoValidation);

            Assert.Equal(TokenValidationStatus.Success, result.Status);

            var jwt = result.Token;

            Assert.Equal(data, jwt.Binary);
        }
Пример #28
0
        protected override Jwks GetKeysFromSource()
        {
            var keys = new List <Jwk>();

            foreach (var keyProperties in _client.GetPropertiesOfKeys())
            {
                var kvKey = _client.GetKey(keyProperties.Name);
                Jwk?key   = null;
                if (kvKey.Value.KeyType == KeyType.Oct)
                {
                    key = SymmetricJwk.FromByteArray(kvKey.Value.Key.K, false);
                }
                else if (kvKey.Value.KeyType == KeyType.Rsa || kvKey.Value.KeyType == KeyType.RsaHsm)
                {
                    key = RsaJwk.FromParameters(kvKey.Value.Key.ToRSA(true).ExportParameters(true), false);
                }
#if !NETFRAMEWORK
                else if (kvKey.Value.KeyType == KeyType.Ec || kvKey.Value.KeyType == KeyType.EcHsm)
                {
                    ECJwk.FromParameters(ConvertToECParameters(kvKey.Value), computeThumbprint: false);
                }
#endif

                if (!(key is null))
                {
                    key.Kid = JsonEncodedText.Encode(kvKey.Value.Key.Id);
                    if (kvKey.Value.Key.KeyOps != null)
                    {
                        foreach (var operation in kvKey.Value.Key.KeyOps)
                        {
                            key.KeyOps.Add(JsonEncodedText.Encode(operation.ToString()));
                        }
                    }

                    keys.Add(key);
                }
            }

            return(new Jwks(_client.VaultUri.ToString(), keys));
        }
Пример #29
0
        // SEQUENCE
        //   INTEGER 0
        //   INTEGER N
        //   INTEGER E
        //   INTEGER D
        //   INTEGER P
        //   INTEGER Q
        //   INTEGER DP
        //   INTEGER DQ
        //   INTEGER QI
        public static RsaJwk ReadRsaPrivateKey(string key)
        {
            string base64KeyData = key.Substring(PrivateRsaKeyPrefix.Length, key.Length - PrivateRsaKeyPrefix.Length - PrivatRsaKeySuffix.Length);

            byte[] keyData = Convert.FromBase64String(base64KeyData);

            var reader = new AsnReader(keyData);

            reader = reader.ReadSequence();
            var version = reader.ReadInteger();

            if (version.Length != 1 || version[0] != 0)
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            var n  = reader.ReadInteger();
            var e  = reader.ReadInteger();
            var d  = reader.ReadInteger();
            var p  = reader.ReadInteger();
            var q  = reader.ReadInteger();
            var dp = reader.ReadInteger();
            var dq = reader.ReadInteger();
            var qi = reader.ReadInteger();

            if (reader.Read())
            {
                ThrowHelper.ThrowInvalidOperationException_InvalidPem();
            }

            return(RsaJwk.FromByteArray(
                       n: AsnReader.TrimLeadingZeroes(n),
                       e: AsnReader.TrimLeadingZeroes(e, align: false),
                       d: AsnReader.TrimLeadingZeroes(d),
                       p: AsnReader.TrimLeadingZeroes(p),
                       q: AsnReader.TrimLeadingZeroes(q),
                       dp: AsnReader.TrimLeadingZeroes(dp),
                       dq: AsnReader.TrimLeadingZeroes(dq),
                       qi: AsnReader.TrimLeadingZeroes(qi)));
        }
Пример #30
0
        private static JweWrapper CreateDescriptor(KeyManagementAlgorithm algorithm, EncryptionAlgorithm encryptionAlgorithm)
        {
            var jwk = algorithm.Category switch
            {
                Cryptography.AlgorithmCategory.None => Jwk.None,
                Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(EllipticalCurve.P256, algorithm),
                Cryptography.AlgorithmCategory.Rsa => RsaJwk.GeneratePrivateKey(4096, algorithm),
                Cryptography.AlgorithmCategory.Aes => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.AesGcm => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Hmac => SymmetricJwk.GenerateKey(algorithm),
                Cryptography.AlgorithmCategory.Direct => SymmetricJwk.GenerateKey(encryptionAlgorithm),
                Cryptography.AlgorithmCategory.Direct | Cryptography.AlgorithmCategory.EllipticCurve => ECJwk.GeneratePrivateKey(EllipticalCurve.P256),
                _ => throw new InvalidOperationException(algorithm.Category.ToString())
            };

            var descriptor = new JweDescriptor(jwk, algorithm, encryptionAlgorithm)
            {
                Payload = new JwsDescriptor(Jwk.None, SignatureAlgorithm.None)
                {
                    Payload = new JwtPayload
                    {
                        { JwtClaimNames.Iat, EpochTime.UtcNow },
                        { JwtClaimNames.Exp, EpochTime.UtcNow + EpochTime.OneHour },
                        { JwtClaimNames.Iss, "https://idp.example.com/" },
                        { JwtClaimNames.Aud, "636C69656E745F6964" }
                    }
                }
            };
            var policy = new TokenValidationPolicyBuilder()
                         .AcceptUnsecureToken("https://idp.example.com/")
                         .WithDecryptionKey(jwk)
                         .Build();

            var writer = new JwtWriter();

            return(new JweWrapper(writer.WriteToken(descriptor), algorithm, encryptionAlgorithm, policy));
        }
    }