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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        public void TestDecryption()
        {
            Blowfish blow  = new Blowfish();
            ulong    crypt = blow.Encrypt(_val);

            if (blow.Decrypt(crypt) != _val)
            {
                throw new Exception("No decryption");
            }
        }
示例#4
0
        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));
        }
示例#5
0
    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);
        }
    }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
        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));
        }
示例#10
0
    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();
    }
示例#11
0
 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();
 }
示例#12
0
        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));
        }
示例#14
0
 public void DecryptBlowfish( )
 {
     Blowfish.Decrypt(_save);
     state = "Blowfish decrypted";
 }