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; } } } }
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); }
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)); }
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); } }
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))); }
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"); } }
//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); }
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); }