public static PasswordRepository Read(
            string repositoryFile,
            string keyDirectory,
            SecureString securePassword,
            bool oldFormat)
        {
            var repository = new PasswordRepository();

            using (var rijAlg = new RijndaelManaged())
            {
                using (var ms = new MemoryStream())
                {
                    ICryptoTransform cryptoTransform;
                    using (var fs = new FileStream(repositoryFile, FileMode.Open))
                    {
                        // read header part of the file
                        repository.Id = ReadId(fs);
                        // read encrypted key and vector for the ID
                        var iv = ReadSecret(keyDirectory, repository.Id, SecretType.IV);
                        if (oldFormat)
                        {
                            var key = Read($"{keyDirectory}\\{repository.Id}.kv");
                            Mix(key, securePassword);
                            rijAlg.Key = key;
                        }
                        else
                        {
                            var encryptedKey = ReadSecret(keyDirectory, repository.Id, SecretType.Key);
                            rijAlg.Key = TransformKey(encryptedKey, iv, securePassword, TransformType.Decrypt);
                        }
                        rijAlg.IV       = iv;
                        cryptoTransform = rijAlg.CreateDecryptor();
                        // decrypt XML part of the file
                        Decrypt(cryptoTransform, fs, ms);
                    }
                    var xmldoc = new XmlDocument();
                    xmldoc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
                    var rootElem = xmldoc.DocumentElement;
                    repository.Name        = rootElem["Name"].InnerText;
                    repository.Description = rootElem["Description"].InnerText;
                    repository.Version     = new Version(rootElem["Version"].InnerText);
                    var entriesElem = rootElem["Passwords"];
                    if (entriesElem.HasChildNodes)
                    {
                        foreach (XmlNode node in entriesElem.ChildNodes)
                        {
                            if (node.Name == "Password")
                            {
                                var passwordElem = node as XmlElement;
                                var pwd          = new Password()
                                {
                                    Name        = passwordElem["Name"].InnerText,
                                    Description = passwordElem["Description"].InnerText,
                                    Url         = passwordElem["Url"].InnerText
                                };
                                if (repository.Version > FILE_FORMAT_050)
                                {
                                    pwd.Id = passwordElem["Id"].InnerText;
                                }
                                // decrypt login and password
                                var cipherLogin = Convert.FromBase64String(passwordElem["CipherLogin"].InnerText);
                                pwd.Login = Decrypt(cryptoTransform, cipherLogin);
                                var cipherPwd = Convert.FromBase64String(passwordElem["CipherPassword"].InnerText);
                                foreach (var c in Decrypt(cryptoTransform, cipherPwd))
                                {
                                    pwd.SecurePassword.AppendChar(c);
                                }
                                Array.Clear(cipherPwd, 0, cipherPwd.Length);
                                pwd.SecurePassword.MakeReadOnly();
                                repository.passwordDict[pwd.Id] = pwd;
                            }
                        }
                    }
                }
            }
            repository.Changed = false;
            return(repository);
        }
Esempio n. 2
0
        public static PasswordRepository Read(
            string repositoryFile,
            string keyDirectory,
            SecureString securePassword,
            bool oldFormat)
        {
            //Представляет базовый класс, от которого должны наследоваться все реализации алгоритма симметричного шифрования Rijndael .
            var repository = new PasswordRepository();

            using (var rijAlg = new RijndaelManaged())
            {
                using (var ms = new MemoryStream())
                {
                    ICryptoTransform cryptoTransform;
                    using (var fs = new FileStream(repositoryFile, FileMode.Open))
                    {
                        // прочитать header part файла
                        repository.Id = ReadId(fs);
                        // прочитать зашифрованный ключ и IV для ID
                        var iv = ReadSecret(keyDirectory, repository.Id, SecretType.IV);
                        if (oldFormat)
                        {
                            var key = Read($"{keyDirectory}\\{repository.Id}.kv");
                            Mix(key, securePassword);
                            rijAlg.Key = key;
                        }
                        else
                        {
                            var encryptedKey = ReadSecret(keyDirectory, repository.Id, SecretType.Key);
                            rijAlg.Key = TransformKey(encryptedKey, iv, securePassword, TransformType.Decrypt);
                        }
                        rijAlg.IV       = iv;
                        cryptoTransform = rijAlg.CreateDecryptor();
                        // расшифровка  XML
                        Decrypt(cryptoTransform, fs, ms);
                    }
                    var xmldoc = new XmlDocument();
                    xmldoc.LoadXml(Encoding.UTF8.GetString(ms.ToArray()));
                    var rootElem = xmldoc.DocumentElement;
                    repository.Name        = rootElem["Name"].InnerText;
                    repository.Description = rootElem["Description"].InnerText;
                    repository.Version     = new Version(rootElem["Version"].InnerText);
                    var entriesElem = rootElem["Passwords"];
                    if (entriesElem.HasChildNodes)
                    {
                        foreach (XmlNode node in entriesElem.ChildNodes)
                        {
                            if (node.Name == "Password")
                            {
                                var passwordElem = node as XmlElement;
                                var pwd          = new Password()
                                {
                                    Name        = passwordElem["Name"].InnerText,
                                    Description = passwordElem["Description"].InnerText,
                                };
                                if (repository.Version > FILE_FORMAT_050)
                                {
                                    pwd.Id = passwordElem["Id"].InnerText;
                                }
                                // расшифровать логин и пароль
                                var cipherLogin = Convert.FromBase64String(passwordElem["CipherLogin"].InnerText);
                                pwd.Login = Decrypt(cryptoTransform, cipherLogin);
                                var cipherPwd = Convert.FromBase64String(passwordElem["CipherPassword"].InnerText);
                                foreach (var c in Decrypt(cryptoTransform, cipherPwd))
                                {
                                    pwd.SecurePassword.AppendChar(c);
                                }
                                Array.Clear(cipherPwd, 0, cipherPwd.Length);
                                pwd.SecurePassword.MakeReadOnly();
                                repository.passwordDict[pwd.Id] = pwd;
                            }
                        }
                    }
                }
            }
            repository.Changed = false;
            return(repository);
        }