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); }
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) }; }
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(); }
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); }
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(); }
public void FromPem_PublicKey(string pem) { var key = RsaJwk.FromPem(pem); AssertKeyEquals(ToPublic(DiminishedDPParameters), key.ExportParameters()); Assert.False(key.HasPrivateKey); }
// 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)); } }
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); }
// 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); } }
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); }
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); }
public void FromPem_UnexpectedKeyType_ThrowArgumentException() { string pem = @" -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgcKEsLbFoRe1W/2jP whpHKz8E19aFG/Y0ny19WzRSs4qhRANCAASBAezkdGSm6tcM9ppuK9PYhpGjJi0i y6T3Y16v8maAqNihK6YdWZI19n2ctNWPF4PTykPnjwpauqYkB5k2wMOp -----END PRIVATE KEY-----"; Assert.Throws <InvalidOperationException>(() => RsaJwk.FromPem(pem)); }
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); }
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); }
// 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))); }
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); } }
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); }
// 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); } }
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); }
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); }
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); }
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())); }
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()); }
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); } }
// 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))); }
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); }
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)); }
// 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))); }
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)); } }