/// <summary> /// Verifies that a signature created over the 'input' matches the signature. Using <see cref="SymmetricSecurityKey"/> and 'algorithm' passed to <see cref="SymmetricSignatureProvider( SecurityKey, string )"/>. /// </summary> /// <param name="input">The bytes to verify.</param> /// <param name="signature">signature to compare against.</param> /// <param name="length">number of bytes of signature to use.</param> /// <returns>true if computed signature matches the signature parameter, false otherwise.</returns> /// <exception cref="ArgumentNullException">'input' is null.</exception> /// <exception cref="ArgumentNullException">'signature' is null.</exception> /// <exception cref="ArgumentException">'input.Length' == 0.</exception> /// <exception cref="ArgumentException">'signature.Length' == 0. </exception> /// <exception cref="ArgumentException">'length < 1'</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose(bool)"/> has been called.</exception> /// <exception cref="InvalidOperationException">If the internal <see cref="KeyedHashAlgorithm"/> is null. This can occur if a derived type deletes it or does not create it.</exception> public bool Verify(byte[] input, byte[] signature, int length) { if (input == null || input.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(input)); } if (signature == null || signature.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(signature)); } if (length < 1) { throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10655, length))); } if (_disposed) { CryptoProviderCache?.TryRemove(this); throw LogHelper.LogExceptionMessage(new ObjectDisposedException(typeof(SymmetricSignatureProvider).ToString())); } LogHelper.LogInformation(LogMessages.IDX10643, input); try { return(Utility.AreEqual(signature, KeyedHashAlgorithm.ComputeHash(input), length)); } catch { CryptoProviderCache?.TryRemove(this); throw; } }
/// <summary> /// Produces a signature over the 'input' using the <see cref="SymmetricSecurityKey"/> and 'algorithm' passed to <see cref="SymmetricSignatureProvider( SecurityKey, string )"/>. /// </summary> /// <param name="input">The bytes to sign.</param> /// <returns>Signed bytes</returns> /// <exception cref="ArgumentNullException">'input' is null. </exception> /// <exception cref="ArgumentException">'input.Length' == 0. </exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose(bool)"/> has been called.</exception> /// <exception cref="InvalidOperationException"><see cref="KeyedHashAlgorithm"/> is null. This can occur if a derived type deletes it or does not create it.</exception> /// <remarks>Sign is thread safe.</remarks> public override byte[] Sign(byte[] input) { if (input == null || input.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(input)); } if (_disposed) { CryptoProviderCache?.TryRemove(this); throw LogHelper.LogExceptionMessage(new ObjectDisposedException(GetType().ToString())); } LogHelper.LogInformation(LogMessages.IDX10642, input); KeyedHashAlgorithm keyedHashAlgorithm = GetKeyedHashAlgorithm(GetKeyBytes(Key), Algorithm); try { return(keyedHashAlgorithm.ComputeHash(input)); } catch { CryptoProviderCache?.TryRemove(this); Dispose(true); throw; } finally { if (!_disposed) { ReleaseKeyedHashAlgorithm(keyedHashAlgorithm); } } }
/// <summary> /// Disposes of internal components. /// </summary> /// <param name="disposing">true, if called from Dispose(), false, if invoked inside a finalizer.</param> protected override void Dispose(bool disposing) { if (!_disposed) { _disposed = true; CryptoProviderCache?.TryRemove(this); if (disposing) { if (_keyedHash != null) { _keyedHash.Dispose(); _keyedHash = null; } } } }
/// <summary> /// Disposes of internal components. /// </summary> /// <param name="disposing">true, if called from Dispose(), false, if invoked inside a finalizer.</param> protected override void Dispose(bool disposing) { if (!_disposed) { _disposed = true; if (disposing) { foreach (var item in _keyedHashObjectPool.Items) { item.Value?.Dispose(); } CryptoProviderCache?.TryRemove(this); } } }
/// <summary> /// Verifies that a signature created over the 'input' matches the signature. Using <see cref="SymmetricSecurityKey"/> and 'algorithm' passed to <see cref="SymmetricSignatureProvider( SecurityKey, string )"/>. /// </summary> /// <param name="input">The bytes to verify.</param> /// <param name="signature">signature to compare against.</param> /// <param name="length">number of bytes of signature to use.</param> /// <returns>true if computed signature matches the signature parameter, false otherwise.</returns> /// <exception cref="ArgumentNullException">'input' is null.</exception> /// <exception cref="ArgumentNullException">'signature' is null.</exception> /// <exception cref="ArgumentException">'input.Length' == 0.</exception> /// <exception cref="ArgumentException">'signature.Length' == 0. </exception> /// <exception cref="ArgumentException">'length < 1'</exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose(bool)"/> has been called.</exception> /// <exception cref="InvalidOperationException">If the internal <see cref="KeyedHashAlgorithm"/> is null. This can occur if a derived type deletes it or does not create it.</exception> public bool Verify(byte[] input, byte[] signature, int length) { if (input == null || input.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(input)); } if (signature == null || signature.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(signature)); } if (length < 1) { throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX10655, length))); } if (_disposed) { CryptoProviderCache?.TryRemove(this); throw LogHelper.LogExceptionMessage(new ObjectDisposedException(GetType().ToString())); } LogHelper.LogInformation(LogMessages.IDX10643, input); KeyedHashAlgorithm keyedHashAlgorithm = GetKeyedHashAlgorithm(GetKeyBytes(Key), Algorithm); try { return(Utility.AreEqual(signature, keyedHashAlgorithm.ComputeHash(input), length)); } catch { CryptoProviderCache?.TryRemove(this); Dispose(true); throw; } finally { if (!_disposed) { ReleaseKeyedHashAlgorithm(keyedHashAlgorithm); } } }
/// <summary> /// Produces a signature over the 'input' using the <see cref="SymmetricSecurityKey"/> and 'algorithm' passed to <see cref="SymmetricSignatureProvider( SecurityKey, string )"/>. /// </summary> /// <param name="input">The bytes to sign.</param> /// <returns>Signed bytes</returns> /// <exception cref="ArgumentNullException">'input' is null. </exception> /// <exception cref="ArgumentException">'input.Length' == 0. </exception> /// <exception cref="ObjectDisposedException"><see cref="Dispose(bool)"/> has been called.</exception> /// <exception cref="InvalidOperationException"><see cref="KeyedHashAlgorithm"/> is null. This can occur if a derived type deletes it or does not create it.</exception> /// <remarks>Sign is thread safe.</remarks> public override byte[] Sign(byte[] input) { if (input == null || input.Length == 0) { throw LogHelper.LogArgumentNullException(nameof(input)); } if (_disposed) { CryptoProviderCache?.TryRemove(this); throw LogHelper.LogExceptionMessage(new ObjectDisposedException(typeof(SymmetricSignatureProvider).ToString())); } LogHelper.LogInformation(LogMessages.IDX10642, input); try { return(KeyedHashAlgorithm.ComputeHash(input)); } catch { CryptoProviderCache?.TryRemove(this); throw; } }
private SignatureProvider CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures) { if (key == null) { throw LogHelper.LogArgumentNullException(nameof(key)); } if (string.IsNullOrEmpty(algorithm)) { throw LogHelper.LogArgumentNullException(nameof(algorithm)); } SignatureProvider signatureProvider = null; if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures)) { signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider; if (signatureProvider == null) { throw LogHelper.LogExceptionMessage(new InvalidOperationException(LogHelper.FormatInvariant(LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider)))); } return(signatureProvider); } // types are checked in order of expected occurrence string typeofSignatureProvider = null; bool createAsymmetric = true; if (key is AsymmetricSecurityKey asymmetricSecurityKey) { typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString(); } else if (key is JsonWebKey jsonWebKey) { if (jsonWebKey.Kty != null) { if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve) { typeofSignatureProvider = typeof(AsymmetricSignatureProvider).ToString(); } if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet) { typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString(); createAsymmetric = false; } } } else if (key is SymmetricSecurityKey symmetricSecurityKey) { typeofSignatureProvider = typeof(SymmetricSignatureProvider).ToString(); createAsymmetric = false; } if (typeofSignatureProvider == null) { throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10621, typeof(SymmetricSignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType()))); } if (!IsSupportedAlgorithm(algorithm, key)) { throw LogHelper.LogExceptionMessage(new NotSupportedException(LogHelper.FormatInvariant(LogMessages.IDX10634, algorithm, key))); } if (CacheSignatureProviders) { if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider)) { return(signatureProvider); } lock (_cacheLock) { if (CryptoProviderCache.TryGetSignatureProvider(key, algorithm, typeofSignatureProvider, willCreateSignatures, out signatureProvider)) { return(signatureProvider); } if (createAsymmetric) { signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures, this); } else { signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures); } CryptoProviderCache.TryAdd(signatureProvider); } } else if (createAsymmetric) { signatureProvider = new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures); } else { signatureProvider = new SymmetricSignatureProvider(key, algorithm, willCreateSignatures); } return(signatureProvider); }