private static IDictionary <string, ProtectedString> OpenKeePassDB(SecureString Password) { PwDatabase PwDB = new PwDatabase(); IOConnectionInfo mioInfo = new IOConnectionInfo { Path = pathToKeePassDb }; CompositeKey compositeKey = new CompositeKey(); compositeKey.AddUserKey(new KcpPassword(Marshal.PtrToStringAuto(Marshal.SecureStringToBSTR(Password)))); IStatusLogger statusLogger = new NullStatusLogger(); Dictionary <string, ProtectedString> dict = new Dictionary <string, ProtectedString>(); try { PwDB.Open(mioInfo, compositeKey, statusLogger); PwObjectList <PwGroup> groups = PwDB.RootGroup.GetGroups(true); if (workingMode == WorkingModes.Prepare) { // Check whether the requested group already exists if (!groups.Any(x => x.Name.Equals(groupName))) { PwDB.RootGroup.AddGroup(new PwGroup() { Name = groupName }, true); Trace.TraceInformation($"The Group {groupName} has been added to KeePass DB"); } PwGroup grp = PwDB.RootGroup.GetGroups(true).Where(x => x.Name.Equals(groupName)).First(); // Check if the required entry doesn't exist in the group if (!grp.GetEntries(false).Any(x => x.Strings.ReadSafe("Title").Equals(entryName))) { //Need to have a local variable for Protected dic //otherwise the clause becomes too complecated for reading ProtectedStringDictionary d = new ProtectedStringDictionary(); d.Set("Title", new ProtectedString(true, entryName)); #pragma warning disable CS0618 // Type or member is obsolete //They tell it is obsolete and recommend to use any other constructor, //but, actually, there's no other to be used. grp.AddEntry(new PwEntry(grp, true, true) { Strings = d }, true); #pragma warning restore CS0618 // Type or member is obsolete Trace.TraceInformation($"The Entry {entryName} has been added to KeePass DB"); } PwEntry ent = grp.GetEntries(false).Where(x => x.Strings.ReadSafe("Title").Equals(entryName)).First(); //Create a value for password ProtectedString aesPwd = new ProtectedString(); PwGenerator.Generate(out aesPwd, new PwProfile() { Length = 16, CharSet = new PwCharSet(PwCharSet.LowerCase + PwCharSet.UpperCase + PwCharSet.Digits + PwCharSet.PrintableAsciiSpecial) }, UTF8Encoding.UTF8.GetBytes(RndString.GetRandomString(16)), new CustomPwGeneratorPool()); //Create a vlaue for Salt ProtectedString salt = new ProtectedString(); PwGenerator.Generate(out salt, new PwProfile() { Length = 26, CharSet = new PwCharSet(PwCharSet.LowerCase + PwCharSet.UpperCase + PwCharSet.Digits + PwCharSet.PrintableAsciiSpecial) }, UTF8Encoding.UTF8.GetBytes(RndString.GetRandomString(28)), new CustomPwGeneratorPool()); ent.Strings.Set("AESpassword", new ProtectedString(true, aesPwd.ReadString())); Trace.TraceInformation($"The value of the AESPass in the Entry {entryName} has been added to KeePass DB"); ent.Strings.Set("Salt", new ProtectedString(true, salt.ReadString())); Trace.TraceInformation($"The value of the Salt in the Entry {entryName} has been added to KeePass DB"); // Create IV SymmetricAlgorithm cipher = SymmetricAlgorithm.Create("AesManaged"); cipher.Mode = CipherMode.CBC; cipher.Padding = PaddingMode.PKCS7; ent.Strings.Set("IV", new ProtectedString(true, Convert.ToBase64String(cipher.IV))); Trace.TraceInformation($"The value of the IV in the Entry {entryName} has been added to KeePass DB"); PwDB.Save(statusLogger); // Add dummy values to the dictionary to pass the check in the end of the method dict.Add("Salt", new ProtectedString(true, ent.Strings.ReadSafe("Salt"))); dict.Add("Password", new ProtectedString(true, "dummy")); dict.Add("AESPass", new ProtectedString(true, ent.Strings.ReadSafe("AESpassword"))); dict.Add("UserName", new ProtectedString(true, "dummy")); dict.Add("IV", new ProtectedString(true, ent.Strings.ReadSafe("IV"))); dict.Add("SecurityToken", new ProtectedString(true, "dummy")); } else { foreach (PwGroup grp in groups) { if (grp.Name.Equals(groupName)) { PwObjectList <PwEntry> entries = grp.GetEntries(false); foreach (PwEntry ent in entries) { if (ent.Strings.ReadSafe("Title").Equals(entryName)) { dict.Add("Salt", new ProtectedString(true, ent.Strings.ReadSafe("Salt"))); dict.Add("Password", new ProtectedString(true, ent.Strings.ReadSafe("Password"))); dict.Add("AESPass", new ProtectedString(true, ent.Strings.ReadSafe("AESpassword"))); dict.Add("UserName", new ProtectedString(true, ent.Strings.ReadSafe("UserName"))); dict.Add("IV", new ProtectedString(true, ent.Strings.ReadSafe("IV"))); dict.Add("SecurityToken", new ProtectedString(true, ent.Strings.ReadSafe("SecurityToken"))); } } } } } } catch (Exception ex) { Trace.TraceError($"Failed to open KeePassDb \n{ex.Message}"); } finally { PwDB.Close(); } //Delete key-value pairs where values are empty dict.Where(d => d.Value.IsEmpty).ToList().ForEach(t => dict.Remove(t.Key)); return(dict); }