Skip to content

Commit

Permalink
Descriptors are now strongly-typed.
Browse files Browse the repository at this point in the history
- Symmetric algorithm with Symmetric key
- RSA algorithm with RSA key
- EC algorithm with EC key
- Password-based algorithm with Symmetric key
  • Loading branch information
ycrumeyrolle committed Jul 23, 2024
1 parent bac5aa2 commit 21e338f
Show file tree
Hide file tree
Showing 36 changed files with 522 additions and 113 deletions.
4 changes: 2 additions & 2 deletions perf/Sandbox/JwsHeaderSerializationCacheBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ public void WithCacheHit_8parameters()
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
public class JweHeaderSerializationCacheBenchmarks
{
private static readonly Jwk _signingKey = SymmetricJwk.GenerateKey(SignatureAlgorithm.HS256);
private static readonly Jwk _encryptionKey = SymmetricJwk.GenerateKey(EncryptionAlgorithm.A128Gcm);
private static readonly SymmetricJwk _signingKey = SymmetricJwk.GenerateKey(SignatureAlgorithm.HS256);
private static readonly SymmetricJwk _encryptionKey = SymmetricJwk.GenerateKey(EncryptionAlgorithm.A128Gcm);
private static readonly DisabledJwtHeaderCache _disabledCache = new DisabledJwtHeaderCache();
private static readonly LruJwtHeaderCache _enabledCache = new LruJwtHeaderCache();
private static readonly FixedSizedBufferWriter _output = new FixedSizedBufferWriter(8192);
Expand Down
6 changes: 3 additions & 3 deletions perf/ValidatePerf/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class Program
private static readonly Jwk signingKey1 = SymmetricJwk.GenerateKey(SignatureAlgorithm.HS256);
private static readonly Jwk signingKey2 = ECJwk.GeneratePrivateKey(SignatureAlgorithm.ES256);
private static readonly Jwk signingKey3 = RsaJwk.GeneratePrivateKey(SignatureAlgorithm.RS256);
private static readonly Jwk encryptionKey1 = SymmetricJwk.GenerateKey(KeyManagementAlgorithm.A128KW);
private static readonly Jwk encryptionKey2 = ECJwk.GeneratePrivateKey(EllipticalCurve.P256, KeyManagementAlgorithm.EcdhEsA256KW);
private static readonly Jwk encryptionKey3 = RsaJwk.GeneratePrivateKey(4096, KeyManagementAlgorithm.RsaOaep256);
private static readonly SymmetricJwk encryptionKey1 = SymmetricJwk.GenerateKey(KeyManagementAlgorithm.A128KW);
private static readonly ECJwk encryptionKey2 = ECJwk.GeneratePrivateKey(EllipticalCurve.P256, KeyManagementAlgorithm.EcdhEsA256KW);
private static readonly RsaJwk encryptionKey3 = RsaJwk.GeneratePrivateKey(4096, KeyManagementAlgorithm.RsaOaep256);
private static readonly ReadOnlyMemory<byte> _jws = CreateJws();
private static readonly TokenValidationPolicy _policy =
new TokenValidationPolicyBuilder()
Expand Down
2 changes: 1 addition & 1 deletion samples/UnsecureJwtCreationSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Program
static void Main()
{
// Creates a JWS descriptor with all its properties
var descriptor = new JwsDescriptor(Jwk.None, SignatureAlgorithm.None)
var descriptor = new JwsDescriptor()
{
Payload = new JwtPayload
{
Expand Down
23 changes: 23 additions & 0 deletions src/JsonWebToken/ECKeyManagementAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2020 Yann Crumeyrolle. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.

using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Defines Elliptical Curve key management algorithm.</summary>
public sealed class ECKeyManagementAlgorithm : KeyManagementAlgorithm
{
/// <summary>Initializes a new instance of <see cref="ECKeyManagementAlgorithm"/>. </summary>
public ECKeyManagementAlgorithm(AlgorithmId id, string name, AlgorithmCategory keyType, KeyManagementAlgorithm wrappedAlgorithm)
: base(id, name, keyType, wrappedAlgorithm)
{
}

/// <summary>Initializes a new instance of <see cref="ECKeyManagementAlgorithm"/>. </summary>
public ECKeyManagementAlgorithm(AlgorithmId id, string name, AlgorithmCategory keyType, bool produceEncryptedKey)
: base(id, name, keyType, produceEncryptedKey)
{
}
}
}
17 changes: 17 additions & 0 deletions src/JsonWebToken/ECSignatureAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2020 Yann Crumeyrolle. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.

using System.Security.Cryptography;
using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Define an Elliptical Curve signature algorithm.</summary>
public sealed class ECSignatureAlgorithm : SignatureAlgorithm
{
/// <summary>Initializes a new instance of <see cref="ECSignatureAlgorithm"/>. </summary>
public ECSignatureAlgorithm(AlgorithmId id, string name, AlgorithmCategory category, ushort requiredKeySizeInBits, HashAlgorithmName hashAlgorithm) : base(id, name, category, requiredKeySizeInBits, hashAlgorithm)
{
}
}
}
81 changes: 41 additions & 40 deletions src/JsonWebToken/KeyManagementAlgorithm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text.Json;
using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Defines key management algorithm.</summary>
public sealed partial class KeyManagementAlgorithm : IEquatable<KeyManagementAlgorithm>, IAlgorithm
public partial class KeyManagementAlgorithm : IEquatable<KeyManagementAlgorithm>, IAlgorithm
{
[MagicNumber("dir")]
private const uint _dir = 7498084U;
Expand Down Expand Up @@ -96,62 +97,62 @@ public sealed partial class KeyManagementAlgorithm : IEquatable<KeyManagementAlg
/// <summary>Empty</summary>
internal static readonly KeyManagementAlgorithm Empty = new KeyManagementAlgorithm(id: 0, "Empty", AlgorithmCategory.None, produceEncryptedKey: false);

/// <summary>'dir'</summary>
public static readonly KeyManagementAlgorithm Dir = new KeyManagementAlgorithm(id: AlgorithmId.Dir, "dir", AlgorithmCategory.Direct, produceEncryptedKey: false);
/// <summary>'dir', Direct use of a shared symmetric key as the CEK.</summary>
public static readonly SymmetricKeyManagementAlgorithm Dir = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.Dir, "dir", AlgorithmCategory.Direct, produceEncryptedKey: false);

/// <summary>'A128KW'</summary>
public static readonly KeyManagementAlgorithm A128KW = new KeyManagementAlgorithm(id: AlgorithmId.A128KW, "A128KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 128);
/// <summary>'A128KW', AES Key Wrap with default initial value using 128-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A128KW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A128KW, "A128KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 128);

/// <summary>'A192KW'</summary>
public static readonly KeyManagementAlgorithm A192KW = new KeyManagementAlgorithm(id: AlgorithmId.A192KW, "A192KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 192);
/// <summary>'A192KW', AES Key Wrap with default initial value using 192-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A192KW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A192KW, "A192KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 192);

/// <summary>'A256KW'</summary>
public static readonly KeyManagementAlgorithm A256KW = new KeyManagementAlgorithm(id: AlgorithmId.A256KW, "A256KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 256);
/// <summary>'A256KW', AES Key Wrap with default initial value using 256-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A256KW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A256KW, "A256KW", AlgorithmCategory.Aes, requiredKeySizeInBits: 256);

/// <summary>'A128GCMKW'</summary>
public static readonly KeyManagementAlgorithm A128GcmKW = new KeyManagementAlgorithm(id: AlgorithmId.A128GcmKW, "A128GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 128);
/// <summary>'A128GCMKW', Key wrapping with AES GCM using 128-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A128GcmKW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A128GcmKW, "A128GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 128);

/// <summary>'A192GCMKW'</summary>
public static readonly KeyManagementAlgorithm A192GcmKW = new KeyManagementAlgorithm(id: AlgorithmId.A192GcmKW, "A192GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 192);
/// <summary>'A192GCMKW', Key wrapping with AES GCM using 192-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A192GcmKW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A192GcmKW, "A192GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 192);

/// <summary>'A256GCMKW'</summary>
public static readonly KeyManagementAlgorithm A256GcmKW = new KeyManagementAlgorithm(id: AlgorithmId.A256GcmKW, "A256GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 256);
/// <summary>'A256GCMKW', Key wrapping with AES GCM using 256-bit key.</summary>
public static readonly SymmetricKeyManagementAlgorithm A256GcmKW = new SymmetricKeyManagementAlgorithm(id: AlgorithmId.A256GcmKW, "A256GCMKW", AlgorithmCategory.AesGcm, requiredKeySizeInBits: 256);

/// <summary>'RSA1_5'. This algorithm is deprecated.</summary>
public static readonly KeyManagementAlgorithm Rsa1_5 = new KeyManagementAlgorithm(id: AlgorithmId.Rsa1_5, "RSA1_5", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);
/// <summary>'RSA1_5', RSAES-PKCS1-v1_5. This algorithm is deprecated.</summary>
public static readonly RsaKeyManagementAlgorithm Rsa1_5 = new RsaKeyManagementAlgorithm(id: AlgorithmId.Rsa1_5, "RSA1_5", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);

/// <summary>'RSA-OAEP'</summary>
public static readonly KeyManagementAlgorithm RsaOaep = new KeyManagementAlgorithm(id: AlgorithmId.RsaOaep, "RSA-OAEP", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);
/// <summary>'RSA-OAEP', RSAES OAEP using SHA-1 and MGF1 with SHA-1.</summary>
public static readonly RsaKeyManagementAlgorithm RsaOaep = new RsaKeyManagementAlgorithm(id: AlgorithmId.RsaOaep, "RSA-OAEP", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);

/// <summary>'RSA-OAEP-128'</summary>
public static readonly KeyManagementAlgorithm RsaOaep256 = new KeyManagementAlgorithm(id: AlgorithmId.RsaOaep256, "RSA-OAEP-256", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);
/// <summary>'RSA-OAEP-128', RSAES OAEP using SHA-256 and MGF1 with SHA-256.</summary>
public static readonly RsaKeyManagementAlgorithm RsaOaep256 = new RsaKeyManagementAlgorithm(id: AlgorithmId.RsaOaep256, "RSA-OAEP-256", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);

/// <summary>'RSA-OAEP-192'</summary>
public static readonly KeyManagementAlgorithm RsaOaep384 = new KeyManagementAlgorithm(id: AlgorithmId.RsaOaep384, "RSA-OAEP-384", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);
/// <summary>'RSA-OAEP-192', RSAES OAEP using SHA-384 and MGF1 with SHA-384.</summary>
public static readonly RsaKeyManagementAlgorithm RsaOaep384 = new RsaKeyManagementAlgorithm(id: AlgorithmId.RsaOaep384, "RSA-OAEP-384", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);

/// <summary>'RSA-OAEP-256'</summary>
public static readonly KeyManagementAlgorithm RsaOaep512 = new KeyManagementAlgorithm(id: AlgorithmId.RsaOaep512, "RSA-OAEP-512", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);
/// <summary>'RSA-OAEP-256', RSAES OAEP using SHA-512 and MGF1 with SHA-512.</summary>
public static readonly RsaKeyManagementAlgorithm RsaOaep512 = new RsaKeyManagementAlgorithm(id: AlgorithmId.RsaOaep512, "RSA-OAEP-512", AlgorithmCategory.Rsa, requiredKeySizeInBits: 2048);

/// <summary>'ECDH-ES'</summary>
public static readonly KeyManagementAlgorithm EcdhEs = new KeyManagementAlgorithm(id: AlgorithmId.EcdhEs, "ECDH-ES", AlgorithmCategory.EllipticCurve | AlgorithmCategory.EllipticCurve, produceEncryptedKey: false);
/// <summary>'ECDH-ES', Elliptic Curve Diffie-Hellman Ephemeral Static key agreement using Concat KDF.</summary>
public static readonly ECKeyManagementAlgorithm EcdhEs = new ECKeyManagementAlgorithm(id: AlgorithmId.EcdhEs, "ECDH-ES", AlgorithmCategory.EllipticCurve | AlgorithmCategory.EllipticCurve, produceEncryptedKey: false);

/// <summary>'ECDH-ES+A128KW'</summary>
public static readonly KeyManagementAlgorithm EcdhEsA128KW = new KeyManagementAlgorithm(id: AlgorithmId.EcdhEsA128KW, "ECDH-ES+A128KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A128KW);
/// <summary>'ECDH-ES+A128KW', ECDH-ES using Concat KDF and CEK wrapped with "A128KW".</summary>
public static readonly ECKeyManagementAlgorithm EcdhEsA128KW = new ECKeyManagementAlgorithm(id: AlgorithmId.EcdhEsA128KW, "ECDH-ES+A128KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A128KW);

/// <summary>'ECDH-ES+A192KW'</summary>
public static readonly KeyManagementAlgorithm EcdhEsA192KW = new KeyManagementAlgorithm(id: AlgorithmId.EcdhEsA192KW, "ECDH-ES+A192KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A192KW);
/// <summary>'ECDH-ES+A192KW', ECDH-ES using Concat KDF and CEK wrapped with "A192KW".</summary>
public static readonly ECKeyManagementAlgorithm EcdhEsA192KW = new ECKeyManagementAlgorithm(id: AlgorithmId.EcdhEsA192KW, "ECDH-ES+A192KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A192KW);

/// <summary>'ECDH-ES+A256KW'</summary>
public static readonly KeyManagementAlgorithm EcdhEsA256KW = new KeyManagementAlgorithm(id: AlgorithmId.EcdhEsA256KW, "ECDH-ES+A256KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A256KW);
/// <summary>'ECDH-ES+A256KW', ECDH-ES using Concat KDF and CEK wrapped with "A256KW".</summary>
public static readonly ECKeyManagementAlgorithm EcdhEsA256KW = new ECKeyManagementAlgorithm(id: AlgorithmId.EcdhEsA256KW, "ECDH-ES+A256KW", AlgorithmCategory.EllipticCurve, wrappedAlgorithm: A256KW);

/// <summary>'PBES2-HS256+A128KW'</summary>
public static readonly KeyManagementAlgorithm Pbes2HS256A128KW = new KeyManagementAlgorithm(id: AlgorithmId.Pbes2HS256A128KW, "PBES2-HS256+A128KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A128KW, sha2: Sha256.Shared);
/// <summary>'PBES2-HS256+A128KW'. This algorithm is dedicated for JWK encryption.</summary>
public static readonly PasswordBasedKeyManagementAlgorithm Pbes2HS256A128KW = new PasswordBasedKeyManagementAlgorithm(id: AlgorithmId.Pbes2HS256A128KW, "PBES2-HS256+A128KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A128KW, sha2: Sha256.Shared);

/// <summary>'PBES2-HS394+A192KW'</summary>
public static readonly KeyManagementAlgorithm Pbes2HS384A192KW = new KeyManagementAlgorithm(id: AlgorithmId.Pbes2HS384A192KW, "PBES2-HS384+A192KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A192KW, sha2: Sha384.Shared);
/// <summary>'PBES2-HS394+A192KW'. This algorithm is dedicated for JWK encryption.</summary>
public static readonly PasswordBasedKeyManagementAlgorithm Pbes2HS384A192KW = new PasswordBasedKeyManagementAlgorithm(id: AlgorithmId.Pbes2HS384A192KW, "PBES2-HS384+A192KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A192KW, sha2: Sha384.Shared);

/// <summary>'PBES2-HS512+A256KW'</summary>
public static readonly KeyManagementAlgorithm Pbes2HS512A256KW = new KeyManagementAlgorithm(id: AlgorithmId.Pbes2HS512A256KW, "PBES2-HS512+A256KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A256KW, sha2: Sha512.Shared);
/// <summary>'PBES2-HS512+A256KW'. This algorithm is dedicated for JWK encryption.</summary>
public static readonly PasswordBasedKeyManagementAlgorithm Pbes2HS512A256KW = new PasswordBasedKeyManagementAlgorithm(id: AlgorithmId.Pbes2HS512A256KW, "PBES2-HS512+A256KW", AlgorithmCategory.Pbkdf2, wrappedAlgorithm: A256KW, sha2: Sha512.Shared);

private readonly AlgorithmId _id;
private readonly ushort _requiredKeySizeInBits;
Expand Down Expand Up @@ -185,7 +186,7 @@ public sealed partial class KeyManagementAlgorithm : IEquatable<KeyManagementAlg
/// <summary>Gets whether the algorithm produce an encryption key.</summary>
public bool ProduceEncryptionKey => _produceEncryptionKey;

internal static readonly KeyManagementAlgorithm[] _algorithms = new[]
internal static readonly KeyManagementAlgorithm[] _algorithms = new KeyManagementAlgorithm[]
{
EcdhEsA128KW,
EcdhEsA256KW,
Expand Down
6 changes: 0 additions & 6 deletions src/JsonWebToken/Obsolete/JwsDescriptor.obsolete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@ namespace JsonWebToken
{
public partial class JwsDescriptor
{
/// <summary>Initializes a new instance of <see cref="JwsDescriptor"/>.</summary>
[Obsolete("This constructor is obsolete. Use the constructor JwsDescriptor(Jwk signingKey, SignatureAlgorithm alg, string? typ = null, string? cty = null) instead.", true)]
[EditorBrowsable(EditorBrowsableState.Never)]
public JwsDescriptor()
=> throw new NotImplementedException();

/// <summary>Gets or sets the algorithm header.</summary>
[Obsolete("This property is obsolete. Use the constructor for passing this value instead.", true)]
[EditorBrowsable(EditorBrowsableState.Never)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace JsonWebToken
{
public sealed partial class KeyManagementAlgorithm
public partial class KeyManagementAlgorithm
{
#pragma warning disable CS8618
/// <summary>'dir'</summary>
Expand Down
2 changes: 1 addition & 1 deletion src/JsonWebToken/Obsolete/SignatureAlgorithm.obsolete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace JsonWebToken
{
public sealed partial class SignatureAlgorithm
public partial class SignatureAlgorithm
{
#pragma warning disable CS8618
/// <summary>'HS256'</summary>
Expand Down
17 changes: 17 additions & 0 deletions src/JsonWebToken/PasswordBasedKeyManagementAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2020 Yann Crumeyrolle. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.

using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Defines password-based key management algorithm.</summary>
public sealed class PasswordBasedKeyManagementAlgorithm : KeyManagementAlgorithm
{
/// <summary>Initializes a new instance of <see cref="PasswordBasedKeyManagementAlgorithm"/>. </summary>
public PasswordBasedKeyManagementAlgorithm(AlgorithmId id, string name, AlgorithmCategory keyType, KeyManagementAlgorithm wrappedAlgorithm, Sha2 sha2)
: base(id, name, keyType, wrappedAlgorithm, sha2)
{
}
}
}
17 changes: 17 additions & 0 deletions src/JsonWebToken/RsaKeyManagementAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2020 Yann Crumeyrolle. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.

using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Defines RSA key management algorithm.</summary>
public sealed class RsaKeyManagementAlgorithm : KeyManagementAlgorithm
{
/// <summary>Initializes a new instance of <see cref="RsaKeyManagementAlgorithm"/>. </summary>
public RsaKeyManagementAlgorithm(AlgorithmId id, string name, AlgorithmCategory keyType, ushort requiredKeySizeInBits)
: base(id, name, keyType, requiredKeySizeInBits)
{
}
}
}
17 changes: 17 additions & 0 deletions src/JsonWebToken/RsaSignatureAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2020 Yann Crumeyrolle. All rights reserved.
// Licensed under the MIT license. See LICENSE in the project root for license information.

using System.Security.Cryptography;
using JsonWebToken.Cryptography;

namespace JsonWebToken
{
/// <summary>Defines a RSA signature algorithm.</summary>
public sealed class RsaSignatureAlgorithm : SignatureAlgorithm
{
/// <summary>Initializes a new instance of <see cref="RsaSignatureAlgorithm"/>. </summary>
public RsaSignatureAlgorithm(AlgorithmId id, string name, AlgorithmCategory category, ushort requiredKeySizeInBits, HashAlgorithmName hashAlgorithm) : base(id, name, category, requiredKeySizeInBits, hashAlgorithm)
{
}
}
}
Loading

0 comments on commit 21e338f

Please sign in to comment.