Пример #1
0
    static void Tally(HashFunction hf, byte[] key)
    {
        uint h0 = hf.ComputeHash(key);

        if (key.Length <= 6)
        {
            for (int i = 0; i < key.Length; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    key[i] ^= (byte)(1 << j);
                    uint h1 = hf.ComputeHash(key) ^ h0;
                    key[i] ^= (byte)(1 << j);
                    int x = i * 8 + j;
                    for (int y = 0; y < 32; y++)
                    {
                        if ((h1 & 1) != 0)
                        {
                            matrix[x, y]++;
                        }
                        h1 >>= 1;
                    }
                }
            }
        }
        else
        {
            for (int j = 0; j < 8; j++)
            {
                key[0] ^= (byte)(1 << j);
                uint h1 = hf.ComputeHash(key) ^ h0;
                key[0] ^= (byte)(1 << j);
                for (int y = 0; y < 32; y++)
                {
                    if ((h1 & 1) != 0)
                    {
                        matrix[j, y]++;
                    }
                    h1 >>= 1;
                }
                key[key.Length - 1] ^= (byte)(1 << j);
                h1 = hf.ComputeHash(key) ^ h0;
                key[key.Length - 1] ^= (byte)(1 << j);
                for (int y = 0; y < 32; y++)
                {
                    if ((h1 & 1) != 0)
                    {
                        matrix[j + 8, y]++;
                    }
                    h1 >>= 1;
                }
            }
        }
    }
Пример #2
0
        public override bool VerifyFile(string filePath, ref List <KeyValuePair <X509Certificate2, bool> > verifiedCMS)
        {
            byte[] DataDigest  = new byte[0];
            byte[] BlockDigest = new byte[0];
            signatureBlock = new Elements(ExtractBlocks(filePath), false);

            //digest of the data without the signature(s)
            DataDigest = Hash(filePath);
            //signatures found in the file
            Dictionary <string, string> Signatures = ExtractAllSignatures(filePath);

            if (Signatures.Count < 1)
            {
                throw new NoSignatureFoundException(filePath);
            }

            List <KeyValuePair <X509Certificate2, bool> > UsedCertificates = new List <KeyValuePair <X509Certificate2, bool> >();

            bool Validation = true;

            foreach (String Signature in Signatures.Keys)
            {
                BlockDigest = HashFunction.ComputeHash(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(Signatures[Signature])));
                byte[] merkleHash = new byte[DataDigest.Length + BlockDigest.Length];
                Array.Copy(DataDigest, merkleHash, DataDigest.Length);
                Array.Copy(BlockDigest, 0, merkleHash, DataDigest.Length, BlockDigest.Length);

                //Content information created from the data digest
                ContentInfo StepContent = new ContentInfo(merkleHash);

                SignedCms SignedCMS = new SignedCms(StepContent, true);
                SignedCMS.Decode(Convert.FromBase64String(Signature));
                SignerInfoEnumerator Enumerator = SignedCMS.SignerInfos.GetEnumerator();
                if (!Enumerator.MoveNext())
                {
                    throw new InvalidSignerInformationException(Signature);
                }

                try
                {
                    //after decoding the signed cms, we check the signature
                    SignedCMS.CheckSignature(true);
                    UsedCertificates.Add(new KeyValuePair <X509Certificate2, bool>(Enumerator.Current.Certificate, true));
                }
                catch (System.Security.Cryptography.CryptographicException e)
                {
                    //signature can't be verified
                    UsedCertificates.Add(new KeyValuePair <X509Certificate2, bool>(Enumerator.Current.Certificate, false));
                    Validation = false;
                }
            }
            verifiedCMS = UsedCertificates;
            return(Validation);
        }
Пример #3
0
        public void TestHash()
        {
            //h из контрольного примера
            var expected = new byte[] { 0xb1, 0x7e, 0xb3, 0xf6, 0x0f, 0x29, 0x0e, 0xfd };
            // сообщение из контрольного примера
            var m      = new byte[] { 0xd4, 0x44, 0x90, 0x7e, 0xfb, 0x8c, 0xf7 };
            var mora   = new HashFunction();
            var result = mora.ComputeHash(m);

            Assert.True(expected.SequenceEqual(result));
        }
Пример #4
0
        public object EncodeCMS(X509Certificate2 certificate, string filePath, int block)
        {
            byte[] hashContent = this.Hash(filePath);
            string traceBlock  = signatureBlock.GetCompleteTrace(block);

            if (traceBlock != null)
            {
                byte[] hashTrace  = HashFunction.ComputeHash(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(traceBlock)));
                byte[] merkleHash = new byte[hashContent.Length + hashTrace.Length];
                Array.Copy(hashContent, merkleHash, hashContent.Length);
                Array.Copy(hashTrace, 0, merkleHash, hashContent.Length, hashTrace.Length);
                return(EncodeCMS(certificate, merkleHash));
            }
            else
            {
                return(null);
            }
        }
Пример #5
0
        protected override byte[] Hash(string filePath)
        {
            //Method is overriden because we only need to compute the hash of the content BEFORE the signature
            //We do not want to cross-sign hence why we need to extract the "real" data from the file
            Thread ThreadStream;
            Thread ThreadRead;

            byte[] DataHash = new byte[0];

            StreamReader FileStream = new StreamReader(filePath);

            #region thread

            ThreadRead = new Thread(reader =>
            {
                //Create a named pipe using the current process ID of this application
                using (NamedPipeServerStream PipeStream = new NamedPipeServerStream("StepSign"))
                {
                    //wait for the streamer to send the data
                    PipeStream.WaitForConnection();
                    using (StreamReader sr = new StreamReader(PipeStream))
                    {
                        DataHash = HashFunction.ComputeHash(sr.BaseStream);
                    }
                }
            });

            ThreadStream = new Thread(streamer =>
            {
                using (NamedPipeClientStream PipeStream = new NamedPipeClientStream("StepSign"))
                {
                    //flag to stop reading
                    string EOD      = "END-ISO-10303-21;";
                    byte[] bEOD     = System.Text.Encoding.ASCII.GetBytes(EOD);
                    int SearchIndex = 0;

                    //we connect to the StepSign pipe as a client to send data
                    PipeStream.Connect();

                    //use a binarywriter on the pipe to stream data
                    using (BinaryWriter sw = new BinaryWriter(PipeStream))
                    {
                        int read = 0;
                        while ((read = FileStream.BaseStream.ReadByte()) != -1)
                        {
                            sw.Write((byte)read);
                            //did we stream all the data yet?
                            if ((byte)read == bEOD[SearchIndex])
                            {
                                SearchIndex += 1;
                                //if we just finished reading the flag, then we just read all the data we need to hash
                                if (SearchIndex >= bEOD.Length)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                SearchIndex = 0;
                            }
                        }
                    }
                }
            });

            ThreadRead.Start();
            ThreadStream.Start();
            ThreadStream.Join();
            #endregion
            FileStream.Close();
            return(DataHash);
        }
 /// <summary>
 /// <see cref="IHasher.Hash(byte[])"/>.
 /// </summary>
 public int Hash(byte[] data)
 {
     return(unchecked ((int)HashFunction.ComputeHash(data)));
 }
Пример #7
0
    static void BitCorrelationTest(HashFunction hf)
    {
        int[,] H = new int[32, 32];
        for (int i = 0; i < 10000; i++)
        {
            byte[] key = null;
            switch (rand.Next(3))
            {
            case 0:
                key = HashFunction.GetUniformKey();
                break;

            case 1:
                key = HashFunction.GetTextKey();
                break;

            case 2:
                key = HashFunction.GetSparseKey();
                break;
            }
            uint hash = hf.ComputeHash(key);
            for (int j = 0; j < 32; j++)
            {
                for (int k = 0; k < 32; k++)
                {
                    if (((hash & (1U << j)) != 0) == ((hash & (1U << k)) != 0))
                    {
                        H[j, k]++;
                    }
                    else
                    {
                        H[j, k]--;
                    }
                }
            }
        }

        using (Bitmap bmp = new Bitmap(255, 255))
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.DrawLine(Pens.Black, 63, 0, 63, 255);
                g.DrawLine(Pens.Black, 127, 0, 127, 255);
                g.DrawLine(Pens.Black, 191, 0, 191, 255);
                g.DrawLine(Pens.Black, 0, 63, 255, 63);
                g.DrawLine(Pens.Black, 0, 127, 255, 127);
                g.DrawLine(Pens.Black, 0, 191, 255, 191);
                for (int j = 0; j < 32; j++)
                {
                    for (int k = 0; k < 32; k++)
                    {
                        Brush br;
                        if (H[j, k] < -233)
                        {
                            br = Brushes.Red;
                        }
                        else if (H[j, k] < -199)
                        {
                            br = Brushes.Orange;
                        }
                        else if (H[j, k] < 199)
                        {
                            br = Brushes.LightGray;
                        }
                        else if (H[j, k] > 233)
                        {
                            br = Brushes.GreenYellow;
                        }
                        else
                        {
                            br = Brushes.YellowGreen;
                        }
                        g.FillRectangle(br, 8 * j + 1, 8 * k + 1, 5, 5);
                    }
                }
                bmp.Save(hf.ToString() + "-bits.gif");
            }
    }
Пример #8
0
        //TODO: Refactor
        protected override byte[] Hash(string filePath)
        {
            Thread tStreamer;
            Thread tDataReader;

            byte[] dataDigest = new byte[0];

            StreamReader sno = new StreamReader(filePath);

            #region thread

            tDataReader = new Thread(reader =>
            {
                //Create a named pipe using the current process ID of this application
                using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("GSign"))
                {
                    //wait for the streamer to send the data
                    pipeStream.WaitForConnection();
                    using (StreamReader sr = new StreamReader(pipeStream))
                    {
                        dataDigest = HashFunction.ComputeHash(sr.BaseStream);
                    }
                }
            });

            tStreamer = new Thread(streamer =>
            {
                using (NamedPipeClientStream pipeStream = new NamedPipeClientStream("GSign"))
                {
                    string EOD    = "M30";
                    byte[] bEOD   = System.Text.Encoding.ASCII.GetBytes(EOD);
                    int searchIdx = 0;

                    //we connect to the StepSign pipe as a client to send data
                    pipeStream.Connect();

                    //use a binarywriter on the pipe to stream data
                    using (BinaryWriter sw = new BinaryWriter(pipeStream))
                    {
                        int read = 0;
                        while ((read = sno.BaseStream.ReadByte()) != -1)
                        {
                            sw.Write((byte)read);

                            if ((byte)read == bEOD[searchIdx])
                            {
                                searchIdx += 1;
                                if (searchIdx >= bEOD.Length)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                searchIdx = 0;
                            }
                        }
                    }
                }
            });

            tDataReader.Start();
            tStreamer.Start();
            tStreamer.Join();
            #endregion
            sno.Close();
            return(dataDigest);
        }
Пример #9
0
        public void TestCollisions()
        {
            var mora = new HashFunction();

            var lst       = new List <List <ulong> >();
            var solutions = new List <ulong[]>();

            // Коллизии найдены заранее
            // 15191912733080746243 : 2816499036862610626
            // 12602365574662108235 : 15317591334086282728
//            2541090681042594495 : 12112829685509080139
//            8325695980190155696 : 10246617843613846309
//            4364755641628337682 : 7731428877087533129
            lst.Add(new List <ulong>()
            {
                4364755641628337682, 7731428877087533129
            });
            lst.Add(new List <ulong>()
            {
                8325695980190155696, 10246617843613846309
            });
            lst.Add(new List <ulong>()
            {
                2541090681042594495, 12112829685509080139
            });
            lst.Add(new List <ulong>()
            {
                12602365574662108235, 15317591334086282728
            });
            lst.Add(new List <ulong>()
            {
                15191912733080746243, 2816499036862610626
            });

            Utils.Solve(lst, solutions, new ulong[lst.Count]);

            var messages = solutions.Select(seq =>
            {
                IEnumerable <byte> ret = new byte[0];

                ret = seq.Aggregate(ret, (current, value) =>
                                    current.Concat(BitConverter.GetBytes(ulong.MaxValue - value + 1).Reverse())
                                    .Concat(BitConverter.GetBytes(value).Reverse()));

                return(ret.ToArray());
            }).ToArray();

            Assert.True(solutions.Count() == 1 << lst.Count());

            bool allMessagesAreDifferent = messages.Distinct(ByteArrayComparer.Default).Count() == messages.Length;

            Assert.True(allMessagesAreDifferent);

            // 2 ^ lst.Count хеши
            var hashes = messages.Select(msg => mora.ComputeHash(msg)).ToArray();

            // Все хеши должны иметь одинаковое значение
            bool allHashesAreEqual = hashes.All(hash => hash.SequenceEqual(hashes.First()));

            Assert.True(allHashesAreEqual);
        }