public void Rfc23279TrySignDataUnderMax() { KeyDescription keyDescription = GetKey(); ECDsa key = (ECDsa)keyDescription.Key; const DSASignatureFormat SignatureFormat = DSASignatureFormat.Rfc3279DerSequence; const int RetryCount = 10; HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1; int expectedSize = GetExpectedSize(keyDescription.FieldSizeInBits); int maxSize = key.GetMaxSignatureSize(DSASignatureFormat.Rfc3279DerSequence); Assert.True(expectedSize < maxSize, "expectedSize < maxSize"); byte[] signature = new byte[expectedSize]; for (int i = 0; i < RetryCount; i++) { if (key.TrySignData(Array.Empty <byte>(), signature, hashAlgorithm, SignatureFormat, out int written)) { return; } Assert.Equal(0, written); } Assert.True(false, $"TrySignData eventually succeeds with a {expectedSize}/{maxSize}-byte destination"); }
public void Rfc23279TrySignHashUnderMax() { KeyDescription keyDescription = GetKey(); ECDsa key = (ECDsa)keyDescription.Key; const DSASignatureFormat SignatureFormat = DSASignatureFormat.Rfc3279DerSequence; const int RetryCount = 10; byte[] hash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; int expectedSize = GetExpectedSize(keyDescription.FieldSizeInBits); int maxSize = key.GetMaxSignatureSize(DSASignatureFormat.Rfc3279DerSequence); Assert.True(expectedSize < maxSize, "expectedSize < maxSize"); byte[] signature = new byte[expectedSize]; for (int i = 0; i < RetryCount; i++) { if (key.TrySignHash(hash, signature, SignatureFormat, out int written)) { return; } Assert.Equal(0, written); } Assert.True(false, $"TrySignHash eventually succeeds with a {expectedSize}/{maxSize}-byte destination"); }
protected override byte[] SignHashCore(ReadOnlySpan <byte> hash, DSASignatureFormat signatureFormat) { if (this.publicKey == null) { CreateKeys(); } if (this.privateKey == null) { throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey); } byte[] signature = NSec.Cryptography.SignatureAlgorithm.Ed25519.Sign(this.privateKey, hash).ToArray(); if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { var writer = new AsnWriter(AsnEncodingRules.DER); using (var sequence = writer.PushSequence()) { writer.WriteIntegerUnsigned(signature.AsSpan(0, 32)); writer.WriteIntegerUnsigned(signature.AsSpan(32)); } signature = writer.Encode(); } return(signature); }
protected override bool VerifySignatureCore( ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, DSASignatureFormat signatureFormat) { Span <byte> stackBuf = stackalloc byte[WindowsMaxQSize]; ReadOnlySpan <byte> source = AdjustHashSizeIfNecessary(hash, stackBuf); if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { // source.Length is the field size, in bytes, so just convert to bits. int fieldSizeBits = source.Length * 8; signature = this.ConvertSignatureToIeeeP1363(signatureFormat, signature, fieldSizeBits); } else if (signatureFormat != DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); throw new CryptographicException( SR.Cryptography_UnknownSignatureFormat, signatureFormat.ToString()); } using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) { unsafe { return(CngCommon.VerifyHash(keyHandle, source, signature, AsymmetricPaddingMode.None, null)); } } }
/// <summary> /// Verifies that a digital signature is valid for the provided data. /// </summary> /// <param name="data">The signed data.</param> /// <param name="signature">The signature to verify.</param> /// <param name="hashAlgorithm">The hash algorithm used to hash the data for the verification process.</param> /// <param name="signatureFormat">The encoding format for <paramref name="signature"/>.</param> /// <returns> /// <see langword="true"/> if the digital signature is valid for the provided data; otherwise, <see langword="false"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> or <paramref name="signature"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="hashAlgorithm"/> has a <see langword="null"/> or empty <see cref="HashAlgorithmName.Name"/>. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or verification operation. /// </exception> public bool VerifyData( Stream data, byte[] signature, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (signature == null) { throw new ArgumentNullException(nameof(signature)); } if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); } if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(VerifyDataCore(data, signature, hashAlgorithm, signatureFormat)); }
protected override bool VerifySignatureCore( ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, DSASignatureFormat signatureFormat) { SafeDsaHandle key = GetKey(); if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { int expectedSignatureBytes = Interop.AndroidCrypto.DsaSignatureFieldSize(key) * 2; if (signature.Length != expectedSignatureBytes) { // The input isn't of the right length (assuming no DER), so we can't sensibly re-encode it with DER. return(false); } signature = AsymmetricAlgorithmHelpers.ConvertIeee1363ToDer(signature); } else if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) { Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); throw new CryptographicException( SR.Cryptography_UnknownSignatureFormat, signatureFormat.ToString()); } return(Interop.AndroidCrypto.DsaVerify(key, hash, signature)); }
public void Rfc3279SignatureValidatesLength() { KeyDescription key = GetKey(); HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1; const DSASignatureFormat SignatureFormat = DSASignatureFormat.Rfc3279DerSequence; byte[] hash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; byte[] signature = SignHash(key, hash, SignatureFormat); byte[] rightPadded = signature.Concat(Enumerable.Repeat((byte)0, 4)).ToArray(); Assert.True( VerifyHash(key, hash, signature, SignatureFormat), "VerifyHash with the unmodified signature"); Assert.False( VerifyHash(key, hash, rightPadded, SignatureFormat), "VerifyHash with the right-padded signature"); signature = SignData(key, hash, hashAlgorithm, SignatureFormat); rightPadded = signature.Concat(Enumerable.Repeat((byte)0, 4)).ToArray(); Assert.True( VerifyData(key, hash, signature, hashAlgorithm, SignatureFormat), "VerifyData with the unmodified signature"); Assert.False( VerifyData(key, hash, rightPadded, hashAlgorithm, SignatureFormat), "VerifyData with the right-padded signature"); }
protected override unsafe bool TrySignHashCore( ReadOnlySpan <byte> hash, Span <byte> destination, DSASignatureFormat signatureFormat, out int bytesWritten) { using (SafeNCryptKeyHandle keyHandle = GetDuplicatedKeyHandle()) { if (!keyHandle.TrySignHash(hash, destination, AsymmetricPaddingMode.None, null, out bytesWritten)) { bytesWritten = 0; return(false); } } if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { return(true); } if (signatureFormat != DSASignatureFormat.Rfc3279DerSequence) { Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); throw new CryptographicException( SR.Cryptography_UnknownSignatureFormat, signatureFormat.ToString()); } return(AsymmetricAlgorithmHelpers.TryConvertIeee1363ToDer( destination.Slice(0, bytesWritten), destination, out bytesWritten)); }
public void Rfc23279TrySignDataUnderMax() { KeyDescription keyDescription = GetKey(); ECDsa key = (ECDsa)keyDescription.Key; const DSASignatureFormat SignatureFormat = DSASignatureFormat.Rfc3279DerSequence; // Make secp521r1 (7/16 chance of being smaller) and mod-8 keys (3/4 chance of being smaller) // have the same 1-in-a-billion chance of failure. int retryCount = keyDescription.FieldSizeInBits % 8 == 1 ? 36 : 15; HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1; int expectedSize = GetExpectedSize(keyDescription.FieldSizeInBits); int maxSize = key.GetMaxSignatureSize(DSASignatureFormat.Rfc3279DerSequence); Assert.True(expectedSize < maxSize, "expectedSize < maxSize"); byte[] signature = new byte[expectedSize]; for (int i = 0; i < retryCount; i++) { if (key.TrySignData(Array.Empty <byte>(), signature, hashAlgorithm, SignatureFormat, out int written)) { return; } Assert.Equal(0, written); } Assert.True(false, $"TrySignData eventually succeeds with a {expectedSize}/{maxSize}-byte destination"); }
protected override byte[] SignHash( KeyDescription key, byte[] hash, DSASignatureFormat signatureFormat) { return(((ECDsa)key.Key).SignHash(hash, signatureFormat)); }
protected override byte[] SignData( KeyDescription key, byte[] data, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { ECDsa dsa = (ECDsa)key.Key; byte[] predictedMax = new byte[dsa.GetMaxSignatureSize(signatureFormat)]; Assert.True( dsa.TrySignData(data, predictedMax, hashAlgorithm, signatureFormat, out int written), "TrySignData with a GetMaxSignatureSize buffer"); if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { // GetMaxSignatureSize should be exactly accurate for P1363. Assert.Equal(predictedMax.Length, written); } if (written == predictedMax.Length) { return(predictedMax); } return(predictedMax.AsSpan(0, written).ToArray()); }
public void Rfc23279TrySignHashUnderMax() { KeyDescription keyDescription = GetKey(); ECDsa key = (ECDsa)keyDescription.Key; const DSASignatureFormat SignatureFormat = DSASignatureFormat.Rfc3279DerSequence; // Make secp521r1 (7/16 chance of being smaller) and mod-8 keys (3/4 chance of being smaller) // have the same 1-in-a-billion chance of failure. int retryCount = keyDescription.FieldSizeInBits % 8 == 1 ? 36 : 15; byte[] hash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; int expectedSize = GetExpectedSize(keyDescription.FieldSizeInBits); int maxSize = key.GetMaxSignatureSize(DSASignatureFormat.Rfc3279DerSequence); Assert.True(expectedSize < maxSize, "expectedSize < maxSize"); byte[] signature = new byte[expectedSize]; for (int i = 0; i < retryCount; i++) { if (key.TrySignHash(hash, signature, SignatureFormat, out int written)) { return; } Assert.Equal(0, written); } Assert.True(false, $"TrySignHash eventually succeeds with a {expectedSize}/{maxSize}-byte destination"); }
/// <summary> /// Verifies that a digital signature is valid for the provided data. /// </summary> /// <param name="data">An array that contains the signed data.</param> /// <param name="offset">The starting index of the signed portion of <paramref name="data"/>.</param> /// <param name="count">The number of bytes in <paramref name="data"/> that were signed.</param> /// <param name="signature">The signature to verify.</param> /// <param name="hashAlgorithm">The hash algorithm used to hash the data for the verification process.</param> /// <param name="signatureFormat">The encoding format for <paramref name="signature"/>.</param> /// <returns> /// <see langword="true"/> if the digital signature is valid for the provided data; otherwise, <see langword="false"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> or <paramref name="signature"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// /// -or- /// /// <paramref name="offset" /> is less than zero. /// /// -or- /// /// <paramref name="count" /> is less than zero. /// /// -or- /// /// <paramref name="offset" /> + <paramref name="count"/> - 1 results in an index that is /// beyond the upper bound of <paramref name="data"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="hashAlgorithm"/> has a <see langword="null"/> or empty <see cref="HashAlgorithmName.Name"/>. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or verification operation. /// </exception> public bool VerifyData( byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { ArgumentNullException.ThrowIfNull(data); if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException(nameof(count)); } ArgumentNullException.ThrowIfNull(signature); ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(VerifyDataCore( new ReadOnlySpan <byte>(data, offset, count), signature, hashAlgorithm, signatureFormat)); }
/// <summary> /// Gets the largest size, in bytes, for a signature produced by this key in the indicated format. /// </summary> /// <param name="signatureFormat">The encoding format for a signature.</param> /// <returns> /// The largest size, in bytes, for a signature produced by this key in the indicated format. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// </exception> public int GetMaxSignatureSize(DSASignatureFormat signatureFormat) { int fieldSizeBits = KeySize; if (fieldSizeBits == 0) { // Coerce the key/key-size into existence ExportParameters(false); fieldSizeBits = KeySize; // This implementation of ECDsa doesn't set KeySize, we can't if (fieldSizeBits == 0) { throw new NotSupportedException(SR.Cryptography_InvalidKeySize); } } switch (signatureFormat) { case DSASignatureFormat.IeeeP1363FixedFieldConcatenation: return(AsymmetricAlgorithmHelpers.BitsToBytes(fieldSizeBits) * 2); case DSASignatureFormat.Rfc3279DerSequence: return(AsymmetricAlgorithmHelpers.GetMaxDerSignatureSize(fieldSizeBits)); default: throw new ArgumentOutOfRangeException(nameof(signatureFormat)); } }
/// <summary> /// Computes the hash value of the specified data and signs it using the specified signature format. /// </summary> /// <param name="data">The data to sign.</param> /// <param name="offset">The offset into <paramref name="data"/> at which to begin hashing.</param> /// <param name="count">The number of bytes to read from <paramref name="data"/>.</param> /// <param name="hashAlgorithm">The hash algorithm to use to create the hash value.</param> /// <param name="signatureFormat">The encoding format to use for the signature.</param> /// <returns> /// The ECDSA signature for the specified data. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// /// -or- /// /// <paramref name="offset" /> is less than zero. /// /// -or- /// /// <paramref name="count" /> is less than zero. /// /// -or- /// /// <paramref name="offset" /> + <paramref name="count"/> - 1 results in an index that is /// beyond the upper bound of <paramref name="data"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="hashAlgorithm"/> has a <see langword="null"/> or empty <see cref="HashAlgorithmName.Name"/>. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or signing operation. /// </exception> public byte[] SignData( byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { if (data == null) { throw new ArgumentNullException(nameof(data)); } if (offset < 0 || offset > data.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (count < 0 || count > data.Length - offset) { throw new ArgumentOutOfRangeException(nameof(count)); } if (string.IsNullOrEmpty(hashAlgorithm.Name)) { throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm)); } if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(SignDataCore(new ReadOnlySpan <byte>(data, offset, count), hashAlgorithm, signatureFormat)); }
private static void CheckLength(KeyDescription key, byte[] signature, DSASignatureFormat signatureFormat) { int fieldSizeBytes = (key.FieldSizeInBits + 7) / 8; switch (signatureFormat) { case DSASignatureFormat.IeeeP1363FixedFieldConcatenation: Assert.Equal(2 * fieldSizeBytes, signature.Length); break; case DSASignatureFormat.Rfc3279DerSequence: { // SEQUENCE(INTEGER, INTEGER) has a minimum length of 8 (30 06 02 01 00 02 01 00) // The maximum length is a bit more complicated: int elemSize = fieldSizeBytes + 1; int integerMax = 2 + GetDerLengthLength(elemSize) + elemSize; int integersMax = 2 * integerMax; int sequenceMax = 2 + GetDerLengthLength(integersMax) + integersMax; Assert.InRange(signature.Length, 8, sequenceMax); break; } default: throw new InvalidOperationException($"No handler for format {signatureFormat}"); } }
protected override bool TryCreateSignatureCore( ReadOnlySpan <byte> hash, Span <byte> destination, DSASignatureFormat signatureFormat, out int bytesWritten) { SafeDsaHandle key = GetKey(); int maxSignatureSize = Interop.Crypto.DsaEncodedSignatureSize(key); Span <byte> signDestination = stackalloc byte[SignatureStackBufSize]; if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { int fieldSizeBytes = Interop.Crypto.DsaSignatureFieldSize(key); int p1363SignatureSize = 2 * fieldSizeBytes; if (destination.Length < p1363SignatureSize) { bytesWritten = 0; return(false); } int fieldSizeBits = fieldSizeBytes * 8; ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, maxSignatureSize, key); bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, fieldSizeBits, destination); Debug.Assert(bytesWritten == p1363SignatureSize); return(true); } else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { if (destination.Length >= maxSignatureSize) { signDestination = destination; } else if (maxSignatureSize > signDestination.Length) { Debug.Fail($"Stack-based signDestination is insufficient ({maxSignatureSize} needed)"); bytesWritten = 0; return(false); } ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, maxSignatureSize, key); if (destination == signDestination) { bytesWritten = derSignature.Length; return(true); } return(Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten)); } else { Debug.Fail($"Missing internal implementation handler for signature format {signatureFormat}"); throw new CryptographicException( SR.Cryptography_UnknownSignatureFormat, signatureFormat.ToString()); } }
protected override byte[] SignData( KeyDescription key, byte[] data, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { return(((ECDsa)key.Key).SignData(data, hashAlgorithm, signatureFormat)); }
protected override bool VerifyHash( KeyDescription key, byte[] hash, byte[] signature, DSASignatureFormat signatureFormat) { return(((ECDsa)key.Key).VerifyHash(hash, signature, signatureFormat)); }
/// <summary> /// Computes the hash value of the specified data and signs it using the specified signature format. /// </summary> /// <param name="data">The data to sign.</param> /// <param name="hashAlgorithm">The hash algorithm to use to create the hash value.</param> /// <param name="signatureFormat">The encoding format to use for the signature.</param> /// <returns> /// The ECDSA signature for the specified data. /// </returns> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or signing operation. /// </exception> protected virtual byte[] SignDataCore( Stream data, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { byte[] hash = HashData(data, hashAlgorithm); return(SignHashCore(hash, signatureFormat)); }
public void SignHashVerifyHash(DSASignatureFormat signatureFormat) { KeyDescription key = GetKey(); byte[] hash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 }; byte[] signature = SignHash(key, hash, signatureFormat); CheckLength(key, signature, signatureFormat); Assert.True(VerifyHash(key, hash, signature, signatureFormat)); }
/// <summary> /// Verifies that a digital signature is valid for the provided data. /// </summary> /// <param name="data">The signed data.</param> /// <param name="signature">The signature to verify.</param> /// <param name="hashAlgorithm">The hash algorithm used to hash the data for the verification process.</param> /// <param name="signatureFormat">The encoding format for <paramref name="signature"/>.</param> /// <returns> /// <see langword="true"/> if the digital signature is valid for the provided data; otherwise, <see langword="false"/>. /// </returns> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or verification operation. /// </exception> protected virtual bool VerifyDataCore( Stream data, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { byte[] hash = HashData(data, hashAlgorithm); return(VerifyHashCore(hash, signature, signatureFormat)); }
public void SignDataVerifyData_SHA1(DSASignatureFormat signatureFormat) { HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1; KeyDescription key = GetKey(); byte[] signature = SignData(key, _typeNameBytes, hashAlgorithm, signatureFormat); CheckLength(key, signature, signatureFormat); Assert.True(VerifyData(key, _typeNameBytes, signature, hashAlgorithm, signatureFormat)); }
protected override bool TrySignHashCore( ReadOnlySpan <byte> hash, Span <byte> destination, DSASignatureFormat signatureFormat, out int bytesWritten) { ThrowIfDisposed(); SafeEcKeyHandle key = _key.Value; int signatureLength = Interop.AndroidCrypto.EcDsaSize(key); Span <byte> signDestination = stackalloc byte[SignatureStackBufSize]; if (signatureFormat == DSASignatureFormat.IeeeP1363FixedFieldConcatenation) { int encodedSize = 2 * AsymmetricAlgorithmHelpers.BitsToBytes(KeySize); if (destination.Length < encodedSize) { bytesWritten = 0; return(false); } ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, signatureLength, key); bytesWritten = AsymmetricAlgorithmHelpers.ConvertDerToIeee1363(derSignature, KeySize, destination); Debug.Assert(bytesWritten == encodedSize); return(true); } else if (signatureFormat == DSASignatureFormat.Rfc3279DerSequence) { if (destination.Length >= signatureLength) { signDestination = destination; } else if (signatureLength > signDestination.Length) { Debug.Fail($"Stack-based signDestination is insufficient ({signatureLength} needed)"); bytesWritten = 0; return(false); } ReadOnlySpan <byte> derSignature = SignHash(hash, signDestination, signatureLength, key); if (destination == signDestination) { bytesWritten = derSignature.Length; return(true); } return(Helpers.TryCopyToDestination(derSignature, destination, out bytesWritten)); } else { throw new ArgumentOutOfRangeException(nameof(signatureFormat)); } }
/// <summary> /// Verifies that a digital signature is valid for the provided data. /// </summary> /// <param name="data">The signed data.</param> /// <param name="signature">The signature to verify.</param> /// <param name="hashAlgorithm">The hash algorithm used to hash the data for the verification process.</param> /// <param name="signatureFormat">The encoding format for <paramref name="signature"/>.</param> /// <returns> /// <see langword="true"/> if the digital signature is valid for the provided data; otherwise, <see langword="false"/>. /// </returns> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or verification operation. /// </exception> protected virtual bool VerifyDataCore( ReadOnlySpan <byte> data, ReadOnlySpan <byte> signature, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { Span <byte> tmp = stackalloc byte[HashBufferStackSize]; ReadOnlySpan <byte> hash = HashSpanToTmp(data, hashAlgorithm, tmp); return(VerifySignatureCore(hash, signature, signatureFormat)); }
protected override bool VerifyHash( KeyDescription key, byte[] hash, byte[] signature, DSASignatureFormat signatureFormat) { ReadOnlySpan <byte> readOnlyHash = hash; ReadOnlySpan <byte> readOnlySignature = signature; return(((ECDsa)key.Key).VerifyHash(readOnlyHash, readOnlySignature, signatureFormat)); }
/// <summary> /// Computes the ECDSA signature for the specified hash value in the indicated format. /// </summary> /// <param name="hash">The hash value to sign.</param> /// <param name="signatureFormat">The encoding format to use for the signature.</param> /// <returns> /// The ECDSA signature for the specified data. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="hash"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the signing operation. /// </exception> public byte[] SignHash(byte[] hash, DSASignatureFormat signatureFormat) { ArgumentNullException.ThrowIfNull(hash); if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(SignHashCore(hash, signatureFormat)); }
/// <summary> /// Computes the hash value of the specified data and signs it using the specified signature format. /// </summary> /// <param name="data">The data to sign.</param> /// <param name="hashAlgorithm">The hash algorithm to use to create the hash value.</param> /// <param name="signatureFormat">The encoding format to use for the signature.</param> /// <returns> /// The ECDSA signature for the specified data. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="data"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="hashAlgorithm"/> has a <see langword="null"/> or empty <see cref="HashAlgorithmName.Name"/>. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the hashing or signing operation. /// </exception> public byte[] SignData(Stream data, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat) { ArgumentNullException.ThrowIfNull(data); ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(SignDataCore(data, hashAlgorithm, signatureFormat)); }
/// <summary> /// Verifies that a digital signature is valid for the provided hash. /// </summary> /// <param name="hash">The signed hash.</param> /// <param name="signature">The signature to verify.</param> /// <param name="signatureFormat">The encoding format for <paramref name="signature"/>.</param> /// <returns> /// <see langword="true"/> if the digital signature is valid for the provided data; otherwise, <see langword="false"/>. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="signatureFormat"/> is not a known format. /// </exception> /// <exception cref="CryptographicException"> /// An error occurred in the verification operation. /// </exception> public bool VerifyHash( ReadOnlySpan <byte> hash, ReadOnlySpan <byte> signature, DSASignatureFormat signatureFormat) { if (!signatureFormat.IsKnownValue()) { throw DSASignatureFormatHelpers.CreateUnknownValueException(signatureFormat); } return(VerifyHashCore(hash, signature, signatureFormat)); }
/// <summary> /// Attempts to create the ECDSA signature for the specified data in the indicated format /// into the provided buffer. /// </summary> /// <param name="data">The data to hash and sign.</param> /// <param name="destination">The buffer to receive the signature.</param> /// <param name="hashAlgorithm">The hash algorithm to use to create the hash value.</param> /// <param name="signatureFormat">The encoding format to use for the signature.</param> /// <param name="bytesWritten"> /// When this method returns, contains a value that indicates the number of bytes written to /// <paramref name="destination"/>. This parameter is treated as uninitialized. /// </param> /// <returns> /// <see langword="true"/> if <paramref name="destination"/> is big enough to receive the signature; /// otherwise, <see langword="false"/>. /// </returns> /// <exception cref="CryptographicException"> /// An error occurred in the signing operation. /// </exception> protected virtual bool TrySignDataCore( ReadOnlySpan <byte> data, Span <byte> destination, HashAlgorithmName hashAlgorithm, DSASignatureFormat signatureFormat, out int bytesWritten) { Span <byte> hashTmp = stackalloc byte[HashBufferStackSize]; ReadOnlySpan <byte> hash = HashSpanToTmp(data, hashAlgorithm, hashTmp); return(TrySignHashCore(hash, destination, signatureFormat, out bytesWritten)); }