private IEnumerable <(ReadOnlyMemory <byte>, string)> GetHashesV1(V1.Internal.ProfileMessage profileMessage, OmniAgreementPublicKey agreementPublicKey, V1.Internal.HashAlgorithm hashAlgorithm) { var results = new Dictionary <ReadOnlyMemory <byte>, string>(); byte[] verificationMessageHash; { var verificationMessage = new V1.Internal.VerificationMessage(profileMessage, agreementPublicKey); if (hashAlgorithm == V1.Internal.HashAlgorithm.Sha2_256) { var hub = new Hub(); verificationMessage.Export(hub.Writer, _bufferPool); verificationMessageHash = Sha2_256.ComputeHash(hub.Reader.GetSequence()); } else { throw new NotSupportedException(nameof(hashAlgorithm)); } } foreach (var password in _passwords) { if (hashAlgorithm.HasFlag(V1.Internal.HashAlgorithm.Sha2_256)) { results.Add(Hmac_Sha2_256.ComputeHash(verificationMessageHash, Sha2_256.ComputeHash(password)), password); } } return(results.Select(item => (item.Key, item.Value))); }
public static uint Verify(OmniHashcash hashcash, ReadOnlySequence <byte> sequence, ReadOnlyMemory <byte> key) { if (hashcash is null) { throw new ArgumentNullException(nameof(hashcash)); } if (hashcash.AlgorithmType == OmniHashcashAlgorithmType.Sha2_256) { var target = Hmac_Sha2_256.ComputeHash(sequence, key.Span); return(MinerHelper.Verify_Simple_Sha2_256(hashcash.Key.Span, target)); } return(0); }
public static async ValueTask <OmniHashcash> Create(ReadOnlySequence <byte> sequence, ReadOnlyMemory <byte> key, OmniHashcashAlgorithmType hashcashAlgorithmType, int limit, TimeSpan timeout, CancellationToken cancellationToken) { if (!EnumHelper.IsValid(hashcashAlgorithmType)) { throw new ArgumentException(nameof(OmniHashcashAlgorithmType)); } await Task.Delay(1, cancellationToken).ConfigureAwait(false); if (hashcashAlgorithmType == OmniHashcashAlgorithmType.Sha2_256) { var target = Hmac_Sha2_256.ComputeHash(sequence, key.Span); var hashcashKey = MinerHelper.Compute_Simple_Sha2_256(target, limit, timeout, cancellationToken); return(new OmniHashcash(OmniHashcashAlgorithmType.Sha2_256, hashcashKey)); } throw new NotSupportedException(nameof(hashcashAlgorithmType)); }
public static bool TryComputeHash(ReadOnlySpan <byte> password, ReadOnlySpan <byte> salt, int iterationCount, Span <byte> destination) { const int hashLength = 32; int keyLength = destination.Length / hashLength; if (destination.Length % hashLength != 0) { keyLength++; } var extendedkeyLength = (salt.Length + 4); Span <byte> extendedkey = extendedkeyLength <= 128 ? stackalloc byte[extendedkeyLength] : new byte[extendedkeyLength]; BytesOperations.Copy(salt, extendedkey, salt.Length); Span <byte> f = stackalloc byte[hashLength]; Span <byte> u = stackalloc byte[hashLength]; for (int i = 0; i < keyLength; i++) { extendedkey[salt.Length] = (byte)(((i + 1) >> 24) & 0xFF); extendedkey[salt.Length + 1] = (byte)(((i + 1) >> 16) & 0xFF); extendedkey[salt.Length + 2] = (byte)(((i + 1) >> 8) & 0xFF); extendedkey[salt.Length + 3] = (byte)(((i + 1)) & 0xFF); Hmac_Sha2_256.TryComputeHash(extendedkey, password, u); BytesOperations.Zero(extendedkey.Slice(salt.Length, 4)); BytesOperations.Copy(u, f, hashLength); for (int j = 1; j < iterationCount; j++) { Hmac_Sha2_256.TryComputeHash(u, password, u); BytesOperations.Xor(f, u, f); } int position = i * hashLength; int remain = Math.Min(hashLength, destination.Length - position); BytesOperations.Copy(f, destination[position..], remain);
public void ComputeHashTest() { // http://tools.ietf.org/html/rfc4868#section-2.7.1 { var base16 = new Base16(ConvertStringCase.Lower); var key = base16.StringToBytes("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"); var value = base16.StringToBytes("4869205468657265"); var result = base16.BytesToString(Hmac_Sha2_256.ComputeHash(value, key)); Assert.True(result == "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7"); } { var random = new Random(); var caseList = new List <int>(); caseList.AddRange(Enumerable.Range(1, 64)); caseList.AddRange(new int[] { 100, 1000, 10000, 1024 * 1024, 1024 * 1024 * 32 }); var buffer = new byte[1024 * 32]; random.NextBytes(buffer); for (int i = 0; i < caseList.Count; i++) { var key = new byte[caseList[i]]; random.NextBytes(key); using (var stream = new MemoryStream(buffer)) using (var hmacSha256 = new HMACSHA256(key)) { Assert.True(BytesOperations.SequenceEqual(hmacSha256.ComputeHash(stream), Hmac_Sha2_256.ComputeHash(buffer, key))); } } } }
private void InternalDequeue(ReadOnlySequence <byte> sequence, Action <ReadOnlySequence <byte> > action) { using var hub = new Hub(); try { if (_version.HasFlag(OmniSecureConnectionVersion.Version1) && _infoV1 != null) { if (_infoV1.CryptoAlgorithm.HasFlag(V1.Internal.CryptoAlgorithm.Aes_256) && _infoV1.HashAlgorithm.HasFlag(V1.Internal.HashAlgorithm.Sha2_256)) { const int headerSize = 8; const int hashLength = 32; const int blockSize = 16; Interlocked.Add(ref _totalReceivedSize, sequence.Length - (headerSize + hashLength)); // 送信済みデータ + 送信するデータのサイズが正しいか検証する { long totalReceivedSize; { Span <byte> totalReceiveSizeBuffer = stackalloc byte[headerSize]; sequence.Slice(0, headerSize).CopyTo(totalReceiveSizeBuffer); totalReceivedSize = (long)BinaryPrimitives.ReadUInt64BigEndian(totalReceiveSizeBuffer); } if (totalReceivedSize != _totalReceivedSize) { throw new OmniSecureConnectionException(); } } // HMACが正しいか検証する { Span <byte> receivedHash = stackalloc byte[hashLength]; sequence.Slice(sequence.Length - hashLength).CopyTo(receivedHash); var computedhash = Hmac_Sha2_256.ComputeHash(sequence.Slice(headerSize, sequence.Length - (headerSize + hashLength)), _infoV1.OtherHmacKey); if (!BytesOperations.SequenceEqual(receivedHash, computedhash)) { throw new OmniSecureConnectionException(); } } sequence = sequence.Slice(headerSize, sequence.Length - (headerSize + hashLength)); using (var aes = Aes.Create()) { aes.KeySize = 256; aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; // IVを読み込む var iv = new byte[16]; sequence.Slice(0, iv.Length).CopyTo(iv); sequence = sequence.Slice(iv.Length); // 暗号化されたデータを復号化する using (var decryptor = aes.CreateDecryptor(_infoV1.OtherCryptoKey, iv)) { var inBuffer = _bufferPool.GetArrayPool().Rent(blockSize); var outBuffer = _bufferPool.GetArrayPool().Rent(blockSize); try { while (sequence.Length > blockSize) { sequence.Slice(0, blockSize).CopyTo(inBuffer.AsSpan(0, blockSize)); var transed = decryptor.TransformBlock(inBuffer, 0, blockSize, outBuffer, 0); hub.Writer.Write(outBuffer.AsSpan(0, transed)); sequence = sequence.Slice(blockSize); } { int remain = (int)sequence.Length; sequence.CopyTo(inBuffer.AsSpan(0, remain)); var remainBuffer = decryptor.TransformFinalBlock(inBuffer, 0, remain); hub.Writer.Write(remainBuffer); hub.Writer.Complete(); } } finally { _bufferPool.GetArrayPool().Return(inBuffer); _bufferPool.GetArrayPool().Return(outBuffer); } } } action.Invoke(hub.Reader.GetSequence()); hub.Reader.Complete(); return; } } } catch (OmniSecureConnectionException e) { throw e; } catch (Exception e) { throw new OmniSecureConnectionException(e.Message, e); } throw new OmniSecureConnectionException("Conversion failed."); }