/// <inheritsdoc /> public override SymmetricJwk WrapKey(Jwk?staticKey, JwtHeader header, Span <byte> destination) { if (header is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header); } var contentEncryptionKey = CreateSymmetricKey(EncryptionAlgorithm, (SymmetricJwk?)staticKey); Span <byte> buffer = stackalloc byte[_saltSizeInBytes + 1 + _algorithmNameLength]; _saltGenerator.Generate(buffer.Slice(_algorithmNameLength + 1)); buffer[_algorithmNameLength] = 0x00; _algorithm.EncodedUtf8Bytes.CopyTo(buffer); Span <byte> derivedKey = stackalloc byte[_keySizeInBytes]; Pbkdf2.DeriveKey(_password, buffer, _hashAlgorithm, _iterationCount, derivedKey); Span <byte> salt = buffer.Slice(_algorithmNameLength + 1, _saltSizeInBytes); Span <byte> b64Salt = stackalloc byte[Base64Url.GetArraySizeRequiredToEncode(salt.Length)]; Base64Url.Encode(salt, b64Salt); header.Add(JwtHeaderParameterNames.P2s, Utf8.GetString(b64Salt)); header.Add(JwtHeaderParameterNames.P2c, _iterationCount); using var keyWrapper = new AesKeyWrapper(derivedKey, EncryptionAlgorithm, _keyManagementAlgorithm); return(keyWrapper.WrapKey(contentEncryptionKey, header, destination)); }
public static IEnumerable <EncodingWrapper> Values() { foreach (var size in sizes) { var d = new byte[size]; RandomNumberGenerator.Fill(d); yield return(new EncodingWrapper(d, new byte[Base64Url.GetArraySizeRequiredToEncode(size)], size)); } }
/// <inheritsdoc /> public override SymmetricJwk WrapKey(Jwk?staticKey, JwtHeader header, Span <byte> destination) { if (header is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header); } var contentEncryptionKey = CreateSymmetricKey(EncryptionAlgorithm, (SymmetricJwk?)staticKey); int bufferSize = _saltSizeInBytes + _algorithmNameLength + 1; byte[]? bufferToReturn = null; Span <byte> buffer = bufferSize > Pbkdf2.SaltSizeThreshold + 18 + 1 // 18 = max alg name length ? (bufferToReturn = ArrayPool <byte> .Shared.Rent(bufferSize)) : stackalloc byte[Pbkdf2.SaltSizeThreshold + 18 + 1]; buffer = buffer.Slice(0, bufferSize); _saltGenerator.Generate(buffer.Slice(_algorithmNameLength + 1)); buffer[_algorithmNameLength] = 0x00; _algorithm.EncodedUtf8Bytes.CopyTo(buffer); Span <byte> derivedKey = stackalloc byte[KeySizeThreshold].Slice(0, _keySizeInBytes); Pbkdf2.DeriveKey(_password, buffer, _hashAlgorithm, _iterationCount, derivedKey); Span <byte> salt = buffer.Slice(_algorithmNameLength + 1, _saltSizeInBytes); int saltLengthB64 = Base64Url.GetArraySizeRequiredToEncode(salt.Length); byte[]? arrayToReturn = null; Span <byte> b64Salt = saltLengthB64 > Pbkdf2.SaltSizeThreshold * 4 / 3 ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(saltLengthB64)) : stackalloc byte[Pbkdf2.SaltSizeThreshold * 4 / 3]; try { int length = Base64Url.Encode(salt, b64Salt); header.Add(JwtHeaderParameterNames.P2s, Utf8.GetString(b64Salt.Slice(0, saltLengthB64))); header.Add(JwtHeaderParameterNames.P2c, _iterationCount); using var keyWrapper = new AesKeyWrapper(derivedKey, EncryptionAlgorithm, _keyManagementAlgorithm); return(keyWrapper.WrapKey(contentEncryptionKey, header, destination)); } finally { if (bufferToReturn != null) { ArrayPool <byte> .Shared.Return(bufferToReturn); } if (arrayToReturn != null) { ArrayPool <byte> .Shared.Return(arrayToReturn); } } }
public EcdsaSignatureVerifier(ECJwk key, SignatureAlgorithm algorithm) : base(algorithm) { Debug.Assert(key != null); Debug.Assert(key.KeySizeInBits == algorithm.RequiredKeySizeInBits); _sha = algorithm.Sha; _hashSize = key.Crv.HashSize; _base64HashSize = Base64Url.GetArraySizeRequiredToEncode(_hashSize); _ecdsaPool = new ObjectPool <ECDsa>(new ECDsaObjectPoolPolicy(key, algorithm)); }
public SymmetricSigner(ReadOnlySpan <byte> key, SignatureAlgorithm algorithm) : base(algorithm) { Debug.Assert(algorithm.Category == AlgorithmCategory.Hmac); if (key.Length << 3 < MinimumKeySizeInBits) { ThrowHelper.ThrowArgumentOutOfRangeException_AlgorithmRequireMinimumKeySize(key.Length << 3, algorithm.Name.ToString(), MinimumKeySizeInBits); } _hashSizeInBytes = Algorithm.RequiredKeySizeInBits >> 2; _base64HashSizeInBytes = Base64Url.GetArraySizeRequiredToEncode(_hashSizeInBytes); _hashAlgorithm = new HmacSha2(algorithm.Sha, key); }
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())); }
public EcdsaSigner(ECJwk key, SignatureAlgorithm algorithm) : base(algorithm) { if (key is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); } if (key.KeySizeInBits < 256) { ThrowHelper.ThrowArgumentOutOfRangeException_SigningKeyTooSmall(key, 256); } _canOnlyVerify = !key.HasPrivateKey; _hashAlgorithm = algorithm.HashAlgorithm; _hashSize = key.Crv.HashSize; _base64HashSize = Base64Url.GetArraySizeRequiredToEncode(_hashSize); _ecdsaPool = new ObjectPool <ECDsa>(new ECDsaObjectPoolPolicy(key, algorithm)); }
public SymmetricSigner(ReadOnlySpan <byte> key, SignatureAlgorithm algorithm) : base(algorithm) { if (key.Length << 3 < MinimumKeySizeInBits) { ThrowHelper.ThrowArgumentOutOfRangeException_AlgorithmRequireMinimumKeySize(key.Length << 3, algorithm.Name, MinimumKeySizeInBits); } if (algorithm.Category != AlgorithmCategory.Hmac) { ThrowHelper.ThrowNotSupportedException_SignatureAlgorithm(algorithm); } _hashSizeInBytes = Algorithm.RequiredKeySizeInBits >> 2; _base64HashSizeInBytes = Base64Url.GetArraySizeRequiredToEncode(_hashSizeInBytes); _hashAlgorithm = Algorithm.Id switch { Algorithms.HmacSha256 => new HmacSha256(key), Algorithms.HmacSha384 => new HmacSha384(key), Algorithms.HmacSha512 => new HmacSha512(key), _ => new NotSupportedHmacSha(algorithm) }; }