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); }
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); }