Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class Database
- {
- public class DBProfile
- {
- public DBProfile(string name, string phrasehash)
- {
- Name = name;
- EncryptedPhraseHash = phrasehash;
- Accounts = new List<Account>();
- }
- [JsonProperty("Name")]
- public string Name { get; set; }
- [JsonProperty("EncryptedPhraseHash")]
- public string EncryptedPhraseHash { get; set; }
- [JsonProperty("Accounts")]
- public List<Account> Accounts { get; set; }
- }
- public class Account
- {
- public Account(string servicename, string username, string encryptedpassword)
- {
- ServiceName = servicename;
- Username = username;
- EncryptedPassword = encryptedpassword;
- }
- [JsonProperty("ServiceName")]
- public string ServiceName { get; set; }
- [JsonProperty("Username")]
- public string Username { get; set; }
- [JsonProperty("EncryptedPassword")]
- public string EncryptedPassword { get; set; }
- }
- public class PhraseHashJson
- {
- public PhraseHashJson(string phrasehash)
- {
- PhraseHash = phrasehash;
- }
- [JsonProperty("PhraseHash")]
- public string PhraseHash { get; set; }
- }
- public static bool IsProfile(string name)
- {
- return File.Exists(name + ".mpr");
- }
- public static DBProfile CreateProfile(string profilename, string profilepassword, string phrase)
- {
- var passhash = Crypto.GenerateHash(profilepassword);
- var phrasehash = Crypto.GenerateHash(phrase);
- var json = new PhraseHashJson(phrasehash);
- var encryptedphrasehash = Crypto.EncryptStringAES(JsonConvert.SerializeObject(json), passhash);
- var newProfile = new DBProfile(profilename, encryptedphrasehash);
- var text = Crypto.EncryptStringAES(JsonConvert.SerializeObject(newProfile), "b_@_51C-$33d");
- File.WriteAllText(profilename + ".mpr", text);
- return newProfile;
- }
- public static void SaveProfile(DBProfile dbProfile)
- {
- var text = Crypto.EncryptStringAES(JsonConvert.SerializeObject(dbProfile), "b_@_51C-$33d");
- File.WriteAllText(dbProfile.Name + ".mpr", text);
- }
- public static void DeleteProfile(string profilename)
- {
- File.Delete(profilename + ".mpr");
- }
- public static DBProfile GetProfile(string profilename)
- {
- var encryptedProfile = File.ReadAllText(profilename + ".mpr");
- var json = Crypto.DecryptStringAES(encryptedProfile, "b_@_51C-$33d");
- return JsonConvert.DeserializeObject<DBProfile>(json);
- }
- public static DBProfile GetProfileByPath(string path)
- {
- var encryptedProfile = File.ReadAllText(path);
- var json = Crypto.DecryptStringAES(encryptedProfile, "b_@_51C-$33d");
- return JsonConvert.DeserializeObject<DBProfile>(json);
- }
- public static List<DBProfile> GetProfiles()
- {
- var paths = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.mpr");
- var profiles = paths.Select(GetProfileByPath).ToList();
- return profiles;
- }
- public static string GeneratePhrase()
- {
- byte[] data = new byte[4];
- var lphrase = new List<string>();
- var wordlist = Properties.Resources.wordlist.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();
- RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
- for (var i = 0; i < 12; i++)
- {
- rngCsp.GetBytes(data);
- int randomNum = BitConverter.ToInt32(data, 0);
- int place = Mod(randomNum, wordlist.Count);
- lphrase.Add(wordlist[place]);
- }
- return string.Join(" ", lphrase);
- }
- public static int Mod(int x, int m)
- {
- int r = x % m;
- return r < 0 ? r + m : r;
- }
- }
- public class Crypto
- {
- private static readonly byte[] Salt = Encoding.ASCII.GetBytes("P&s$w0<rd__>_^*_M6n2g#r"); //todo: do something about this
- public static string GenerateHash(string plaintext)
- {
- var plainText = Encoding.UTF8.GetBytes(plaintext);
- HashAlgorithm algorithm = new SHA256Managed();
- var plainTextWithSaltBytes = new byte[plainText.Length + Salt.Length];
- for (var i = 0; i < plainText.Length; i++)
- plainTextWithSaltBytes[i] = plainText[i];
- for (var i = 0; i < Salt.Length; i++)
- plainTextWithSaltBytes[plainText.Length + i] = Salt[i];
- return Convert.ToBase64String(algorithm.ComputeHash(plainTextWithSaltBytes));
- }
- public static string GenerateHashWithSeed(string plaintext, string salt)
- {
- HashAlgorithm algorithm = new SHA256Managed();
- var plainText = Encoding.UTF8.GetBytes(plaintext);
- var saltBytes = Encoding.UTF8.GetBytes(salt);
- var plainTextWithSaltBytes = new byte[plainText.Length + saltBytes.Length];
- for (var i = 0; i < plainText.Length; i++)
- plainTextWithSaltBytes[i] = plainText[i];
- for (var i = 0; i < saltBytes.Length; i++)
- plainTextWithSaltBytes[plainText.Length + i] = saltBytes[i];
- return Convert.ToBase64String(algorithm.ComputeHash(plainTextWithSaltBytes));
- }
- /// <summary>
- /// Encrypt the given string using AES. The string can be decrypted using
- /// DecryptStringAES(). The sharedSecret parameters must match.
- /// </summary>
- /// <param name="plainText">The text to encrypt.</param>
- /// <param name="sharedSecret">A password used to generate a key for encryption.</param>
- public static string EncryptStringAES(string plainText, string sharedSecret)
- {
- if (string.IsNullOrEmpty(plainText))
- throw new ArgumentNullException("plainText");
- if (string.IsNullOrEmpty(sharedSecret))
- throw new ArgumentNullException("sharedSecret");
- string outStr; // encrypted string to return
- try
- {
- // generate the key from the shared secret and the salt
- var key = new Rfc2898DeriveBytes(sharedSecret, Salt);
- // Create a RijndaelManaged object
- var aesAlg = new RijndaelManaged();
- aesAlg.Key = key.GetBytes(aesAlg.KeySize/8);
- // Create a decryptor to perform the stream transform.
- ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
- // Create the streams used for encryption.
- using (var msEncrypt = new MemoryStream())
- {
- // prepend the IV
- msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof (int));
- msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
- using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
- using (var swEncrypt = new StreamWriter(csEncrypt))
- swEncrypt.Write(plainText); //Write all data to the stream.
- outStr = Convert.ToBase64String(msEncrypt.ToArray());
- }
- aesAlg.Clear();
- }
- catch (Exception ex)
- {
- Console.WriteLine("Error: {0}", ex);
- return "";
- }
- // Return the encrypted bytes from the memory stream.
- return outStr;
- }
- /// <summary>
- /// Decrypt the given string. Assumes the string was encrypted using
- /// EncryptStringAES(), using an identical sharedSecret.
- /// </summary>
- /// <param name="cipherText">The text to decrypt.</param>
- /// <param name="sharedSecret">A password used to generate a key for decryption.</param>
- public static string DecryptStringAES(string cipherText, string sharedSecret)
- {
- if (string.IsNullOrEmpty(cipherText))
- throw new ArgumentNullException("cipherText");
- if (string.IsNullOrEmpty(sharedSecret))
- throw new ArgumentNullException("sharedSecret");
- // Declare the string used to hold
- // the decrypted text.
- string plaintext;
- try
- {
- // generate the key from the shared secret and the salt
- var key = new Rfc2898DeriveBytes(sharedSecret, Salt);
- // Create the streams used for decryption.
- var bytes = Convert.FromBase64String(cipherText);
- using (var msDecrypt = new MemoryStream(bytes))
- {
- var aesAlg = new RijndaelManaged(); // Create a RijndaelManaged object with the specified key and IV.
- aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
- // Get the initialization vector from the encrypted stream
- aesAlg.IV = ReadByteArray(msDecrypt);
- // Create a decrytor to perform the stream transform.
- var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
- using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
- using (var srDecrypt = new StreamReader(csDecrypt))
- plaintext = srDecrypt.ReadToEnd(); // Read the decrypted bytes from the decrypting stream and place them in a string.
- aesAlg.Clear();
- }
- }
- catch (Exception ex)
- {
- Console.WriteLine("Error: {0}", ex);
- return "";
- }
- return plaintext;
- }
- private static byte[] ReadByteArray(Stream s)
- {
- var rawLength = new byte[sizeof(int)];
- if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
- throw new SystemException("Stream did not contain properly formatted byte array");
- var buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
- if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
- throw new SystemException("Did not read byte array properly");
- return buffer;
- }
- }
- public class Profile
- {
- public string ProfileName;
- public bool LoggedIn = false;
- private Database.DBProfile _dbProfile;
- private string _phraseHash;
- public Profile(Database.DBProfile dbProfile)
- {
- _dbProfile = dbProfile;
- ProfileName = _dbProfile.Name;
- }
- public Database.Account AddAccount(string servicename, string username, string password)
- {
- // If password was generated by the program we don't need to save it, just the variables we can use to regenerate it
- var encryptedpassword = (password == null) ? null : Crypto.EncryptStringAES(password, _phraseHash);
- var newAccount = new Database.Account(servicename, username, encryptedpassword); // Create account object
- // Make sure profile does not already have an account with that name
- if (_dbProfile.Accounts.Any(a => (a.Username == username) && (a.ServiceName == servicename))) return null;
- // Add account to profile
- _dbProfile.Accounts.Add(newAccount); // Add account to profile objects list
- Database.SaveProfile(_dbProfile); // Save account in database
- return newAccount;
- }
- public bool Login(string password)
- {
- var passwordHash = Crypto.GenerateHash(password); // Get password hash
- try
- {
- var encryptedphrasehash = Crypto.DecryptStringAES(_dbProfile.EncryptedPhraseHash, passwordHash); // Try to decrypt phrase with given password, throws if invalid
- _phraseHash = JsonConvert.DeserializeObject<Database.PhraseHashJson>(encryptedphrasehash).PhraseHash; // Get phrase hash from decrypted profile
- LoggedIn = true;
- return true;
- }
- catch (Exception) // Wrong password
- {
- return false;
- }
- }
- public void Logout()
- {
- RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
- for (var i = 0; i < 3; i++)
- {
- byte[] data = new byte[(int) Math.Round((double) (_phraseHash.Count()))];
- rngCsp.GetBytes(data);
- int randomNum = BitConverter.ToInt32(data, 0);
- _phraseHash = randomNum.ToString();
- }
- LoggedIn = false;
- _phraseHash = null;
- }
- public string GetAccountPassword(int accountIndex)
- {
- Database.Account account = _dbProfile.Accounts[accountIndex];
- // If encrypted password is null the password was generated with the program so we just re-generate it
- // If it isn't null the password was given by the user so we need to decrypt it
- return (account.EncryptedPassword == null)
- ? Crypto.GenerateHashWithSeed(account.ServiceName + account.Username, _phraseHash)
- : Crypto.DecryptStringAES(account.EncryptedPassword, _phraseHash);
- }
- public void Delete()
- {
- if (LoggedIn) Logout(); // Erase phrase hash
- Database.DeleteProfile(ProfileName);
- }
- public List<Database.Account> GetAccounts()
- {
- return _dbProfile.Accounts;
- }
- public void DeleteAccount(int index)
- {
- var accountRemove = _dbProfile.Accounts[index];
- _dbProfile.Accounts.Remove(accountRemove);
- Database.SaveProfile(_dbProfile);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement