private string createHexOutputFromDigest(byte[] digestBytes) { IDigest digest = new WhirlpoolDigest(); byte[] resBuf = new byte[digest.GetDigestSize()]; digest.BlockUpdate(digestBytes, 0, digestBytes.Length); digest.DoFinal(resBuf, 0); return(Hex.ToHexString(resBuf)); }
public static byte[] ComputeWhirlpoolDigest(byte[] data) { IDigest digest = new WhirlpoolDigest(); byte[] buffer = new byte[digest.GetDigestSize()]; digest.BlockUpdate(data, 0, data.Length); digest.DoFinal(buffer, 0); return(buffer); }
public static string CalcCustomAlgorithm1(string password, string salt) // Leet CC { // SHA-512(pass.salt) XOR whirlpool(salt.pass) string toWhirlpool = salt + password; byte[] sha512Out = CalcSHA512Raw(password + salt); WhirlpoolDigest digest = new WhirlpoolDigest(); digest.BlockUpdate(Encoding.UTF8.GetBytes(toWhirlpool), 0, toWhirlpool.Length); byte[] whirlpoolOut = new byte[digest.GetByteLength()]; digest.DoFinal(whirlpoolOut, 0); // xor together and convert to hex byte[] finalOut = exclusiveOR(sha512Out, whirlpoolOut); return(ToHexString(finalOut)); }
public static string Hash(string message) { if (string.IsNullOrEmpty(message) || string.IsNullOrWhiteSpace(message)) { return(string.Empty); } //ASCIIEncoding encoding = new ASCIIEncoding(); WhirlpoolDigest whirlpool = new WhirlpoolDigest(); UTF8Encoding encoding = new UTF8Encoding(); byte[] data = encoding.GetBytes(message); whirlpool.Reset(); whirlpool.BlockUpdate(data, 0, data.Length); byte[] ret = new byte[whirlpool.GetDigestSize()]; whirlpool.DoFinal(ret, 0); return(ByteToString(ret)); }
/// <summary> /// Whirlpool computation /// </summary> /// <param name="data">the data to hash</param> /// <param name="key">optional hmac key</param> /// <returns>the hash value</returns> private static byte[] ComputeWhirlpool(byte[] data, byte[] key) { byte[] outData = new byte[64]; if (key != null) { var poolHmac = new HMac(new WhirlpoolDigest()); poolHmac.Init(new KeyParameter(key)); poolHmac.BlockUpdate(data, 0, data.Length); poolHmac.DoFinal(outData, 0); } else { var digest = new WhirlpoolDigest(); digest.BlockUpdate(data, 0, data.Length); digest.DoFinal(outData, 0); } return(outData); }
public override void Decode(byte[] data) { if (this.Info == null) { throw new DecodeException("File info must be set before decoding binary file."); } var dataReader = new BinaryReader(new MemoryStream(data)); this.Info.CompressionType = (CompressionType)dataReader.ReadByte(); var dataLength = dataReader.ReadInt32BigEndian(); // Total length includes already read bytes and the extra bytes read because of compression var totalLength = (this.Info.CompressionType == CompressionType.None ? 5 : 9) + dataLength; // Decrypt the data if a key is given if (this.Info.EncryptionKey != null) { var xtea = new XteaEngine(); xtea.Init(false, new KeyParameter(this.Info.EncryptionKey)); var decrypted = new byte[totalLength]; xtea.ProcessBlock(dataReader.ReadBytes(totalLength), 5, decrypted, 0); dataReader = new BinaryReader(new MemoryStream(decrypted)); } // Check if we should decompress the data or not if (this.Info.CompressionType == CompressionType.None) { this.Info.UncompressedSize = dataLength; this.Data = dataReader.ReadBytes(dataLength); } else { // Decompress the data this.Info.CompressedSize = dataLength; this.Info.UncompressedSize = dataReader.ReadInt32BigEndian(); var compressedBytes = dataReader.ReadBytes(dataLength); var uncompressedBytes = new byte[this.Info.UncompressedSize.Value]; switch (this.Info.CompressionType) { case CompressionType.Bzip2: // Add the bzip2 header as it is missing from the cache for whatever reason var bzipCompressedBytes = new byte[compressedBytes.Length + 4]; bzipCompressedBytes[0] = (byte)'B'; bzipCompressedBytes[1] = (byte)'Z'; bzipCompressedBytes[2] = (byte)'h'; bzipCompressedBytes[3] = (byte)'1'; Array.Copy(compressedBytes, 0, bzipCompressedBytes, 4, compressedBytes.Length); using (var bzip2Stream = new BZip2InputStream(new MemoryStream(bzipCompressedBytes))) { var readBzipBytes = bzip2Stream.Read(uncompressedBytes, 0, this.Info.UncompressedSize.Value); if (readBzipBytes != this.Info.UncompressedSize) { throw new DecodeException("Uncompressed container data length does not match obtained length."); } } break; case CompressionType.Gzip: using (var gzipStream = new GZipInputStream(new MemoryStream(compressedBytes))) { var readGzipBytes = gzipStream.Read(uncompressedBytes, 0, this.Info.UncompressedSize.Value); if (readGzipBytes != this.Info.UncompressedSize) { throw new DecodeException("Uncompressed container data length does not match obtained length."); } } break; case CompressionType.Lzma: using (var compressedStream = new MemoryStream(compressedBytes)) using (var uncompressedStream = new MemoryStream(uncompressedBytes)) { var lzmaDecoder = new SevenZip.Compression.LZMA.Decoder(); lzmaDecoder.Code(compressedStream, uncompressedStream, compressedStream.Length, -1, null); if (uncompressedStream.Length != this.Info.UncompressedSize) { throw new DecodeException("Uncompressed container data length does not match obtained length."); } uncompressedBytes = uncompressedStream.ToArray(); } break; default: throw new DecodeException("Invalid compression type given."); } this.Data = uncompressedBytes; } // Update and verify obtained info // Read and verify the version of the file var versionRead = false; if (dataReader.BaseStream.Length - dataReader.BaseStream.Position >= 2) { var version = dataReader.ReadUInt16BigEndian(); if (this.Info.Version != null) { // The version is truncated to 2 bytes, so only the least significant 2 bytes are compared var truncatedInfoVersion = (int)(ushort)this.Info.Version; if (version != truncatedInfoVersion) { throw new DecodeException($"Obtained version part ({version}) did not match expected ({truncatedInfoVersion})."); } } else { // Set obtained version if previously unset this.Info.Version = version; } versionRead = true; } // Calculate and verify CRC // CRC excludes the version of the file added to the end // There is no way to know if the CRC is zero or unset var crcHasher = new Crc32(); crcHasher.Update(data.Take(data.Length - (versionRead ? 2 : 0)).ToArray()); var crc = (int)crcHasher.Value; if (this.Info.Crc != null && crc != this.Info.Crc) { throw new DecodeException($"Calculated checksum (0x{crc:X}) did not match expected (0x{this.Info.Crc:X})."); } this.Info.Crc = crc; // Calculate and verify the whirlpool digest var whirlpoolHasher = new WhirlpoolDigest(); whirlpoolHasher.BlockUpdate(data, 0, data.Length - (versionRead ? 2 : 0)); var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()]; whirlpoolHasher.DoFinal(whirlpoolDigest, 0); if (this.Info.WhirlpoolDigest != null && !whirlpoolDigest.SequenceEqual(this.Info.WhirlpoolDigest)) { throw new DecodeException("Calculated whirlpool digest did not match expected."); } this.Info.WhirlpoolDigest = whirlpoolDigest; if (dataReader.BaseStream.Position < dataReader.BaseStream.Length) { throw new DecodeException($"Input data not fully consumed while decoding binary file. {dataReader.BaseStream.Length - dataReader.BaseStream.Position} bytes remain."); } }
public override byte[] Encode() { if (this.Info == null) { throw new DecodeException("File info must be set before encoding binary file."); } // Encrypt data if (this.Info.EncryptionKey != null) { throw new NotImplementedException("RuneTek5 file encryption is not yet supported. Nag me about it if you encounter this error."); } // Compression var uncompressedSize = this.Data.Length; byte[] compressedData; switch (this.Info.CompressionType) { case CompressionType.Bzip2: using (var bzip2CompressionStream = new MemoryStream()) { using (var bzip2Stream = new BZip2OutputStream(bzip2CompressionStream, 1)) { bzip2Stream.Write(this.Data, 0, this.Data.Length); } // Remove BZh1 compressedData = bzip2CompressionStream.ToArray().Skip(4).ToArray(); } break; case CompressionType.Gzip: using (var gzipCompressionStream = new MemoryStream()) { using (var gzipStream = new GZipOutputStream(gzipCompressionStream)) { gzipStream.Write(this.Data, 0, this.Data.Length); } compressedData = gzipCompressionStream.ToArray(); } break; case CompressionType.Lzma: using (var lzmaCompressionStream = new MemoryStream()) using (var dataStream = new MemoryStream(this.Data)) { var lzmaEncoder = new SevenZip.Compression.LZMA.Encoder(); lzmaEncoder.Code(dataStream, lzmaCompressionStream, this.Data.Length, -1, null); compressedData = lzmaCompressionStream.ToArray(); } break; case CompressionType.None: compressedData = this.Data; break; default: throw new ArgumentException("Invalid compression type."); } var memoryStream = new MemoryStream(); var writer = new BinaryWriter(memoryStream); writer.Write((byte)this.Info.CompressionType); // Compressed/total size writer.WriteInt32BigEndian(compressedData.Length); // Add uncompressed size when compressing if (this.Info.CompressionType != CompressionType.None) { writer.WriteInt32BigEndian(uncompressedSize); } writer.Write(compressedData); // Suffix with version truncated to two bytes (not part of data for whatever reason) if (this.Info.Version != null) { writer.WriteUInt16BigEndian((ushort)this.Info.Version); } var result = memoryStream.ToArray(); // Update file info with sizes this.Info.CompressedSize = compressedData.Length; this.Info.UncompressedSize = uncompressedSize; // Update file info with CRC var crc = new Crc32(); crc.Update(result.Take(result.Length - 2).ToArray()); this.Info.Crc = (int)crc.Value; // Update file info with whirlpool digest var whirlpool = new WhirlpoolDigest(); whirlpool.BlockUpdate(result, 0, result.Length - 2); this.Info.WhirlpoolDigest = new byte[whirlpool.GetDigestSize()]; whirlpool.DoFinal(this.Info.WhirlpoolDigest, 0); return(result); }
protected byte[] DecodeData(byte[] encodedData, CacheFileInfo info) { using var dataStream = new MemoryStream(encodedData); using var dataReader = new BinaryReader(dataStream); // Decrypt the data if a key is given if (info.EncryptionKey != null) { throw new DecodeException( "XTEA encryption not supported. If you encounter this please inform me about the index and file that triggered this message." ); // var totalLength = dataStream.Position + dataLength; // // var xtea = new XteaEngine(); // xtea.Init(false, new KeyParameter(info.EncryptionKey)); // var decrypted = new byte[totalLength]; // xtea.ProcessBlock(dataReader.ReadBytes(totalLength), 5, decrypted, 0); // // dataReader = new BinaryReader(new MemoryStream(decrypted)); } var compressionType = (CompressionType)dataReader.ReadByte(); var compressedSize = dataReader.ReadInt32BigEndian(); var uncompressedSize = compressedSize; if (compressionType != CompressionType.None) { uncompressedSize = dataReader.ReadInt32BigEndian(); } var data = this.Decompress( compressionType, dataReader.ReadBytesExactly(compressedSize), uncompressedSize ); // Compressed size includes meta bytes for info. compressedSize = (int)dataStream.Position; // Verify compressed size. Info's compressed size includes meta bytes. if (info.CompressedSize != null && compressedSize != info.CompressedSize) { throw new DecodeException( $"Compressed size ({compressedSize}) does not equal expected ({info.CompressedSize})." ); } // Verify uncompressed size. if (info.UncompressedSize != null && uncompressedSize != info.UncompressedSize) { // Some uncompressed files _do_ seem to include meta bytes into the uncompressed size. Allow for now. // TODO: Figure out when uncompressed size includes the meta bytes. Is this only true for audio files? var message = $"Uncompressed size ({uncompressedSize}) does not equal expected ({info.UncompressedSize})."; if (compressionType == CompressionType.None && uncompressedSize + 5 == info.UncompressedSize) { Log.Debug(message + " (allowed)"); } else { throw new DecodeException(message); } } // Calculate and verify CRC. var crcHasher = new Crc32(); crcHasher.Update(encodedData); // Note that there is no way to distinguish between an unset CRC and one that is zero. var crc = (int)crcHasher.Value; if (info.Crc != null && crc != info.Crc) { throw new DecodeException($"Calculated checksum ({crc}) did not match expected ({info.Crc})."); } // Calculate and verify whirlpool digest. var whirlpoolHasher = new WhirlpoolDigest(); whirlpoolHasher.BlockUpdate(encodedData, 0, compressedSize); var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()]; whirlpoolHasher.DoFinal(whirlpoolDigest, 0); if (info.WhirlpoolDigest != null && !whirlpoolDigest.SequenceEqual(info.WhirlpoolDigest)) { throw new DecodeException("Calculated whirlpool digest did not match expected."); } if (dataStream.Position < dataStream.Length) { throw new DecodeException( $"Input data not fully consumed while decoding RuneTek5CacheFile. {dataStream.Length - dataStream.Position} bytes remain." ); } // Update info with obtained details. info.CompressionType = compressionType; info.CompressedSize = compressedSize; info.UncompressedSize = uncompressedSize; info.Crc = crc; info.WhirlpoolDigest = whirlpoolDigest; return(data); }
protected byte[] EncodeData(byte[] data, CacheFileInfo?info) { // Encrypt data. if (info?.EncryptionKey != null) { throw new EncodeException( "XTEA encryption not supported. If you encounter this please inform me about the index and file that triggered this message." ); } // Compression. var compressionType = info?.CompressionType ?? CompressionType.Bzip2; var uncompressedSize = data.Length; var compressedData = this.CompressData(compressionType, data); using var dataStream = new MemoryStream(); using var dataWriter = new BinaryWriter(dataStream); dataWriter.Write((byte)compressionType); dataWriter.WriteInt32BigEndian(compressedData.Length); // Add uncompressed size if compression is used. if (compressionType != CompressionType.None) { dataWriter.WriteInt32BigEndian(uncompressedSize); } dataWriter.Write(compressedData); if (compressionType == CompressionType.None) { // Uncompressed size includes meta bytes for info when not using compression. uncompressedSize = (int)dataStream.Position; } // Compressed size includes meta bytes for info. var compressedSize = (int)dataStream.Position; var result = dataStream.ToArray(); // Calculate new CRC. var crcHasher = new Crc32(); crcHasher.Update(result); var crc = (int)crcHasher.Value; // Calculate new whirlpool digest. var whirlpoolHasher = new WhirlpoolDigest(); whirlpoolHasher.BlockUpdate(result, 0, compressedSize); var whirlpoolDigest = new byte[whirlpoolHasher.GetDigestSize()]; whirlpoolHasher.DoFinal(whirlpoolDigest, 0); // Update file info. if (info != null) { info.CompressionType = compressionType; info.CompressedSize = compressedSize; info.UncompressedSize = uncompressedSize; info.Crc = crc; info.WhirlpoolDigest = whirlpoolDigest; } return(result); }