コード例 #1
0
ファイル: OmniSecureConnection.cs プロジェクト: lulzzz/omnix
        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)));
        }
コード例 #2
0
    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);
    }
コード例 #3
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));
    }
コード例 #4
0
    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);
コード例 #5
0
ファイル: Hmac_Sha2_256_Tests.cs プロジェクト: lulzzz/omnix
        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)));
                        }
                }
            }
        }
コード例 #6
0
ファイル: OmniSecureConnection.cs プロジェクト: lulzzz/omnix
        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.");
        }