private static void DecryptArchiveSave(KIFHDR hdr, List <KIFENTRY> entries, uint tocSeed, uint fileKey, Blowfish blowfish, int keyIndex, Stream inStream, Stream outStream, KifintProgressArgs progress, KifintProgressCallback callback) { BinaryReader reader = new BinaryReader(inStream); BinaryWriter writer = new BinaryWriter(outStream); const int ProgressThreshold = 1; progress.EntryName = null; progress.EntryIndex = 0; progress.EntryCount = entries.Count; // Decrypt the KIFINT entries using the file key for (uint i = 0; i < hdr.EntryCount; i++, progress.EntryIndex++) { if (unchecked ((int)i) == keyIndex) { continue; } KIFENTRY entry = entries[unchecked ((int)i)]; // Give the entry the correct name UnobfuscateFileName(entry.FileNameRaw, unchecked (tocSeed + i)); // Apply the extra offset to be decrypted entry.Offset += i; // Decrypt the entry's length and offset blowfish.Decrypt(ref entry.Info); progress.EntryName = entry.FileName; if (i % ProgressThreshold == 0 || i + 1 == hdr.EntryCount) { callback?.Invoke(progress); } // Goto the entry's decrypted offset, read the buffer, then decrypt it inStream.Position = entry.Offset; byte[] buffer = reader.ReadBytes(entry.Length); blowfish.Decrypt(buffer, entry.Length & ~7); // Move to the entry's offset in the output stream and write the buffer outStream.Position = entry.Offset; writer.Write(buffer); // Make sure to reassign the entry to the list, because // it's not an array and does not return struct references. entries[unchecked ((int)i)] = entry; } entries.RemoveAt(keyIndex); hdr.EntryCount--; outStream.Position = 0; writer.WriteUnmanaged(hdr); writer.WriteUnmanagedArray(entries); }
/// <summary> /// executes a selftest /// </summary> /// <remarks> /// Call this method to make sure that the instance is able to produce /// valid output according to the specification. /// </remarks> /// <returns> /// true: selftest passed / false: selftest failed /// </returns> public static bool SelfTest() { uint unHi = TEST_VECTOR_PLAIN[0]; uint unLo = TEST_VECTOR_PLAIN[1]; Blowfish bf = new Blowfish(TEST_KEY); bf.Encrypt(ref unHi, ref unLo); if ((unHi != TEST_VECTOR_CIPHER[0]) || (unLo != TEST_VECTOR_CIPHER[1])) { return(false); } bf.Decrypt(ref unHi, ref unLo); if ((unHi != TEST_VECTOR_PLAIN[0]) || (unLo != TEST_VECTOR_PLAIN[1])) { return(false); } return(true); }
public void TestDecryption() { Blowfish blow = new Blowfish(); ulong crypt = blow.Encrypt(_val); if (blow.Decrypt(crypt) != _val) { throw new Exception("No decryption"); } }
public static bool Decrypt(byte[] data, int offset, int length, ClientCryptData cryptData = null) { if (length % 8 != 0) { throw new ArgumentOutOfRangeException(nameof(length), "The lenght must be a multiple of 8!"); } Blowfish.Decrypt(data, offset, length); return(VerifyChecksum(data, offset, length)); }
public void EncryptDecryptTest() { for (var i = 0; i < 100; ++i) { var clear = RandomString.Generate(200, RandomString.Chars.All); var pass = RandomString.Generate(32, RandomString.Chars.English | RandomString.Chars.Numbers); var bf = new Blowfish(pass); var encrypted = bf.Encrypt(clear); var decrypted = bf.Decrypt(encrypted); Assert.True(clear == decrypted); } }
static MemoryStream Decrypt(uint[] h, Blowfish fish) { var decrypted = fish.Decrypt(h); var ms = new MemoryStream(); var writer = new BinaryWriter(ms); foreach (var t in decrypted) { writer.Write(t); } writer.Flush(); ms.Seek(0, SeekOrigin.Begin); return(ms); }
static MemoryStream Decrypt(uint[] h, Blowfish fish) { uint[] decrypted = fish.Decrypt(h); var ms = new MemoryStream(); var writer = new BinaryWriter(ms); foreach (uint t in decrypted) { writer.Write(t); } writer.Flush(); ms.Position = 0; return(ms); }
public static bool Decrypt(byte[] data, int offset, int length, ClientCryptData cryptData) { if (length % 8 != 0) { throw new ArgumentOutOfRangeException(nameof(length), "The lenght must be a multiple of 8!"); } var uintData = new uint[length / 4]; Buffer.BlockCopy(data, offset, uintData, 0, length); var x = SwitchEndianInt(BitConverter.ToUInt32(cryptData.MD5, 0)); var y = SwitchEndianInt(BitConverter.ToUInt32(cryptData.MD5, 4)); for (var i = 0; i < (length / 8); ++i) { //Switch endian first var a2 = i * 2; uintData[a2] = SwitchEndianInt(uintData[a2]); uintData[a2 + 1] = SwitchEndianInt(uintData[a2 + 1]); //Store new XOR var x2 = uintData[a2]; var y2 = uintData[a2 + 1]; Blowfish.Decrypt(uintData, a2, cryptData.Key); uintData[a2] ^= x; uintData[a2 + 1] ^= y; //Update XOR x = x2; y = y2; //Switch endian now uintData[a2] = SwitchEndianInt(uintData[a2]); uintData[a2 + 1] = SwitchEndianInt(uintData[a2 + 1]); } Buffer.BlockCopy(uintData, 0, data, offset, length); return(true); }
MemoryStream DecryptHeader(VirtualFile reader) { byte[] keyblock = reader.Read(80); byte[] blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock); // Decrypt just the 1st block to determine the number of items, and thereby the length of the header var fish = new Blowfish(blowfishKey); uint[] h = fish.Decrypt(ReadUints(reader, 2)); // First 2 decrypted bytes indicate number of files defined in header ushort numFiles = (ushort)(h[0] & 0xFFFF); // now we can determine the actual header length, rounded up to full number of blocks const int blockSize = 8; int headerLength = (6 + numFiles * MixEntry.Size + (blockSize - 1)) & ~(blockSize - 1); // Decrypt full header reader.Position = 84; return(Decrypt(ReadUints(reader, headerLength / 4), fish)); }
static void TestBlowfish() { if (!Blowfish.SelfTest()) { System.Console.WriteLine("selftest failed."); return; } System.Console.WriteLine("selftest passed."); byte[] key = new byte[16]; for (byte bI = 0; bI < key.Length; bI++) { key[bI] = bI; } Blowfish bf = new Blowfish(key); System.Console.WriteLine((bf.IsWeakKey) ? "weak key detected." : "no weak key."); String sTest = "this is something to encrypt"; System.Console.WriteLine(sTest); byte[] plainText = StringToBlocks(sTest); byte[] cipherText = new byte[plainText.Length]; bf.Encrypt(plainText, cipherText, 0, 0, plainText.Length); System.Console.WriteLine(BlocksToString(cipherText)); bf.Decrypt(cipherText, cipherText, 0, 0, cipherText.Length); System.Console.WriteLine(BlocksToString(cipherText)); int nI, nSize = Blowfish.BLOCKSIZE * BIGBUFDIM; byte[] bigBuf = new byte[nSize]; for (nI = 0; nI < nSize; nI++) { bigBuf[nI] = (byte)nI; } System.Console.WriteLine("benchmark running ..."); long lTm = DateTime.Now.Ticks; for (nI = 0; nI < TESTLOOPS; nI++) { bf.Encrypt(bigBuf, bigBuf, 0, 0, nSize); if ((nI & 0x0f) == 0) { System.Console.Write("."); } } lTm = DateTime.Now.Ticks - lTm; lTm /= 10000; System.Console.WriteLine("\n{0} bytes in {1} millisecs", TESTLOOPS * nSize, lTm); long lSize = (long)nSize * 1000 * TESTLOOPS; lSize /= lTm; System.Console.WriteLine("(average of {0} bytes per second)", lSize); bf.Burn(); }
public static void BlowfishTest() { Console.WriteLine("Enter text: "); string text = Console.ReadLine(); Blowfish b = new Blowfish(); string encr = b.Encrypt(text); Console.WriteLine("Encrypted text " + encr); Console.WriteLine("Decrypted text " + b.Decrypt(encr)); Console.ReadKey(); }
public void OnMessageReceived(WaveServerComponent dest, Enum msgID, WaveMessage data) { if (msgID is UserManagerMessageID) { if (data != null) { switch ((UserManagerMessageID)msgID) { case UserManagerMessageID.Challenge: { bool createAccount = false; // check if there is login already (otherwise set defaults) if (!Core.Application.HasLogin) { createAccount = true; Core.Application.UpdateCredentials(GenerateNewUsername(), StringHelper.GetBytes(DefaultPassword)); } // get CSL version WaveCSLVersion serverCSL = (WaveCSLVersion)(data[UserManagerFieldID.CSLVersion].AsShort() ?? (short)WaveCSLVersion.Unknown); switch (serverCSL) { case WaveCSLVersion.Version5: case WaveCSLVersion.Version4: Core.CSLVersion = serverCSL; break; default: Core.CSLVersion = WaveCSLVersion.Version3; break; } // get maximum protocol version WaveProtocolVersion serverProto = (WaveProtocolVersion)(data[UserManagerFieldID.MaxWeMessageVersion].AsByte() ?? (byte)WaveProtocolVersion.Unknown); switch (serverProto) { case WaveProtocolVersion.Version4: Core.ProtocolVersion = WaveProtocolVersion.Version4; break; default: Core.ProtocolVersion = WaveProtocolVersion.Version3; break; } // get challenge BinaryField challenge = (BinaryField)data[UserManagerFieldID.Challenge]; // assemble login message WaveMessage msgOut = new WaveMessage(); msgOut.AddInt16(UserManagerFieldID.CSLVersion, (short)Core.CSLVersion); msgOut.AddBoolean(UserManagerFieldID.EncryptSession, Core.UseEncryption); msgOut.AddInt16(UserManagerFieldID.PriorityMask, NetworkAgent.PrioritiesActiveMask); msgOut.AddBinary(UserManagerFieldID.UserCredentials, ProcessChallenge(challenge.Data, Core.Application, createAccount)); msgOut.AddBoolean(UserManagerFieldID.CreateAccount, createAccount); // cache hash byte[] cacheHash = Core.Cache.CacheHash; msgOut.AddBinary(CacheAgentFieldID.CacheHashCompressed, (cacheHash.Length > 0) ? CompressionHelper.GZipBuffer(cacheHash) : cacheHash); // cache ID (if any) if (Core.Cache.CacheID.HasValue) { msgOut.AddBinary(MessageOutFieldID.CacheItemID, Core.Cache.CacheID.Value.ToByteArray()); } // compiling device settings FieldList deviceSettingsList = FieldList.CreateField(UserManagerFieldID.DeviceSettings); deviceSettingsList.AddString(UserManagerFieldID.DeviceBuildID, Core.BuildID); deviceSettingsList.AddBoolean(NaviAgentFieldID.DeviceSupportsTouch, true); deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceScreenResolutionWidth, 480); deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceScreenResolutionHeight, 800); DeviceGroup[] devs = Core.System.SupportedDeviceGroups; foreach (DeviceGroup dev in devs) { deviceSettingsList.AddInt16(NaviAgentFieldID.DeviceProfileGroup, (short)dev); } deviceSettingsList.AddString(UserManagerFieldID.LanguageID, CultureInfo.CurrentCulture.Name); deviceSettingsList.AddString(UserManagerFieldID.Timezone, Core.Settings.TimeZone); deviceSettingsList.AddBoolean(UserManagerFieldID.AlphaSupport, true); deviceSettingsList.AddBoolean(UserManagerFieldID.CompressionSupport, true); msgOut.AddFieldList(deviceSettingsList); // compiling application request list FieldList appRequestList = FieldList.CreateField(UserManagerFieldID.ApplicationRequest); appRequestList.AddString(NaviAgentFieldID.ApplicationURN, Core.Application.URI); appRequestList.AddInt16(NaviAgentFieldID.ApplicationRequestAction, (short)AppRequestAction.GetAppEntryPage); msgOut.AddFieldList(appRequestList); msgOut.Send(WaveServerComponent.UserManager, UserManagerMessageID.Login); Core.UI.SignalViewNavigationStart(Core.UI.RootViewID); break; } case UserManagerMessageID.EncryptionKeys: { // setting encryption (if allowed by build configuration) if (Core.UseEncryption && (sessionHandshakeFish != null)) { BinaryField sessionKeyField = (BinaryField)data[UserManagerFieldID.SessionKey]; byte[] sessionKey = (byte[])sessionKeyField.Data; sessionHandshakeFish.Decrypt(sessionKey, sessionKey.Length); BinaryField globalServerKeyField = (BinaryField)data[UserManagerFieldID.GlobalServerKey]; byte[] globalServerKey = (byte[])globalServerKeyField.Data; sessionHandshakeFish.Decrypt(globalServerKey, globalServerKey.Length); Core.NotifyEncryptionKeysChanged(this, sessionKey, globalServerKey); } else { Core.NotifyEncryptionKeysChanged(this, null, null); } // setting login data StringField userName = (StringField)data[UserManagerFieldID.CreatedAccountUserName]; if (userName != null) { BinaryField userPass = (BinaryField)data[UserManagerFieldID.CreatedAccountPasswordHash]; if ((userPass != null) && (sessionHandshakeFish != null)) { byte[] passBuffer = (byte[])userPass.Data.Clone(); sessionHandshakeFish.Decrypt(passBuffer, passBuffer.Length); Core.Application.UpdateCredentials(userName.Data, passBuffer); // no longer needed sessionHandshakeFish = null; } } break; } case UserManagerMessageID.LoginResponse: { if (!authenticated) { Int16Field loginStatus = (Int16Field)data[UserManagerFieldID.LoginStatus]; switch ((UserLoginStatus)loginStatus.Data) { case UserLoginStatus.Success: { // signal authentication success Core.NotifyAuthentication(this, data[UserManagerFieldID.SessionInfo].AsByteArray()); // preparing login data message FieldList appContext = (FieldList)data[UserManagerFieldID.ApplicationContext]; if (appContext != null) { int appID = appContext[MessageOutFieldID.ApplicationID].AsInteger() ?? 0; string unqualifiedAppURI = appContext[UserManagerFieldID.ApplicationUnqualifiedURI].AsText(); string fullyQualifiedAppURI = appContext[UserManagerFieldID.ApplicationFullyQualifiedURI].AsText(); Core.NotifySuccessfulLogin(this, appID, unqualifiedAppURI, fullyQualifiedAppURI); } authenticated = true; authenticatedEver = true; break; } case UserLoginStatus.FailedInvalidCredentials: Core.NotifyTerminateSession(this, SessionTerminationReasonCode.InvalidCredentials); break; case UserLoginStatus.FailedNoUser: Core.NotifyTerminateSession(this, SessionTerminationReasonCode.NoSuchUser); break; } } break; } } } } }
/// <summary> /// Decrypts the KIFINT archives using the known archive type, install directory, and name of executable with /// the V_CODE2 used to decrypt. /// </summary> /// <param name="type">The type of archive to look for and decrypt.</param> /// <param name="stream">The stream to the open KIFINT archive.</param> /// <param name="installDir">The installation directory for both the archives and executable.</param> /// <param name="exePath">The path to the executable to extract the V_CODE2 key from.</param> /// <returns>The <see cref="KifintLookup"/> merged with all loaded archives.</returns> /// /// <exception cref="ArgumentNullException"> /// <paramref name="stream"/>, <paramref name="kifintPath"/>, or <paramref name="exePath"/> is null. /// </exception> /// <exception cref="ObjectDisposedException"> /// The <paramref name="stream"/> is closed. /// </exception> private static KifintArchive LoadLookup(KifintType type, Stream stream, string kifintPath, string vcode2, KifintProgressArgs progress, KifintProgressCallback callback) { if (kifintPath == null) { throw new ArgumentNullException(nameof(kifintPath)); } if (vcode2 == null) { throw new ArgumentNullException(nameof(vcode2)); } BinaryReader reader = new BinaryReader(stream); KIFHDR hdr = reader.ReadUnmanaged <KIFHDR>(); UnexpectedFileTypeException.ThrowIfInvalid(hdr.Signature, KIFHDR.ExpectedSignature); KIFENTRY[] entries = reader.ReadUnmanagedArray <KIFENTRY>(hdr.EntryCount); progress.EntryName = null; progress.EntryIndex = 0; progress.EntryCount = entries.Length; // Table of contents seed uint tocSeed = GenerateTocSeed(vcode2); uint fileKey = 0; int fileKeyIndex = -1; Blowfish blowfish = null; // Obtain the decryption file key if one exists for (int i = 0; i < hdr.EntryCount; i++) { if (entries[i].FileName == KeyFileName) { fileKey = MersenneTwister.GenRand(entries[i].Length); blowfish = CatDebug.NewBlowfish(fileKey); fileKeyIndex = i; break; } } const int ProgressThreshold = 500; // Decrypt the KIFINT entries using the file key if (fileKeyIndex != -1) { for (uint i = 0; i < hdr.EntryCount; i++, progress.EntryIndex++) { if (unchecked ((int)i) == fileKeyIndex) { continue; } // Give the entry the correct name UnobfuscateFileName(entries[i].FileNameRaw, unchecked (tocSeed + i)); // Apply the extra offset before decryption entries[i].Offset += i; // Decrypt the entry's offset and length blowfish.Decrypt(ref entries[i].Info); progress.EntryName = entries[i].FileName; if (i % ProgressThreshold == 0 || i + 1 == hdr.EntryCount) { callback?.Invoke(progress); } } } return(new KifintArchive(kifintPath, entries, fileKeyIndex != -1, fileKey, type, blowfish)); }
public void DecryptBlowfish( ) { Blowfish.Decrypt(_save); state = "Blowfish decrypted"; }