Advertisement
Guest User

Untitled

a guest
Sep 15th, 2016
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.08 KB | None | 0 0
  1. public class Database
  2. {
  3. public class DBProfile
  4. {
  5. public DBProfile(string name, string phrasehash)
  6. {
  7. Name = name;
  8. EncryptedPhraseHash = phrasehash;
  9. Accounts = new List<Account>();
  10. }
  11.  
  12. [JsonProperty("Name")]
  13. public string Name { get; set; }
  14.  
  15. [JsonProperty("EncryptedPhraseHash")]
  16. public string EncryptedPhraseHash { get; set; }
  17.  
  18. [JsonProperty("Accounts")]
  19. public List<Account> Accounts { get; set; }
  20. }
  21.  
  22. public class Account
  23. {
  24. public Account(string servicename, string username, string encryptedpassword)
  25. {
  26. ServiceName = servicename;
  27. Username = username;
  28. EncryptedPassword = encryptedpassword;
  29. }
  30.  
  31. [JsonProperty("ServiceName")]
  32. public string ServiceName { get; set; }
  33.  
  34. [JsonProperty("Username")]
  35. public string Username { get; set; }
  36.  
  37. [JsonProperty("EncryptedPassword")]
  38. public string EncryptedPassword { get; set; }
  39. }
  40.  
  41. public class PhraseHashJson
  42. {
  43. public PhraseHashJson(string phrasehash)
  44. {
  45. PhraseHash = phrasehash;
  46. }
  47.  
  48. [JsonProperty("PhraseHash")]
  49. public string PhraseHash { get; set; }
  50. }
  51.  
  52. public static bool IsProfile(string name)
  53. {
  54. return File.Exists(name + ".mpr");
  55. }
  56.  
  57. public static DBProfile CreateProfile(string profilename, string profilepassword, string phrase)
  58. {
  59. var passhash = Crypto.GenerateHash(profilepassword);
  60. var phrasehash = Crypto.GenerateHash(phrase);
  61.  
  62. var json = new PhraseHashJson(phrasehash);
  63. var encryptedphrasehash = Crypto.EncryptStringAES(JsonConvert.SerializeObject(json), passhash);
  64.  
  65. var newProfile = new DBProfile(profilename, encryptedphrasehash);
  66. var text = Crypto.EncryptStringAES(JsonConvert.SerializeObject(newProfile), "b_@_51C-$33d");
  67.  
  68. File.WriteAllText(profilename + ".mpr", text);
  69. return newProfile;
  70. }
  71.  
  72. public static void SaveProfile(DBProfile dbProfile)
  73. {
  74. var text = Crypto.EncryptStringAES(JsonConvert.SerializeObject(dbProfile), "b_@_51C-$33d");
  75.  
  76. File.WriteAllText(dbProfile.Name + ".mpr", text);
  77. }
  78.  
  79. public static void DeleteProfile(string profilename)
  80. {
  81. File.Delete(profilename + ".mpr");
  82. }
  83.  
  84. public static DBProfile GetProfile(string profilename)
  85. {
  86. var encryptedProfile = File.ReadAllText(profilename + ".mpr");
  87. var json = Crypto.DecryptStringAES(encryptedProfile, "b_@_51C-$33d");
  88.  
  89. return JsonConvert.DeserializeObject<DBProfile>(json);
  90. }
  91.  
  92. public static DBProfile GetProfileByPath(string path)
  93. {
  94. var encryptedProfile = File.ReadAllText(path);
  95. var json = Crypto.DecryptStringAES(encryptedProfile, "b_@_51C-$33d");
  96.  
  97. return JsonConvert.DeserializeObject<DBProfile>(json);
  98. }
  99.  
  100. public static List<DBProfile> GetProfiles()
  101. {
  102. var paths = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.mpr");
  103. var profiles = paths.Select(GetProfileByPath).ToList();
  104.  
  105. return profiles;
  106. }
  107.  
  108. public static string GeneratePhrase()
  109. {
  110. byte[] data = new byte[4];
  111. var lphrase = new List<string>();
  112. var wordlist = Properties.Resources.wordlist.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList();
  113. RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
  114. for (var i = 0; i < 12; i++)
  115. {
  116. rngCsp.GetBytes(data);
  117. int randomNum = BitConverter.ToInt32(data, 0);
  118. int place = Mod(randomNum, wordlist.Count);
  119. lphrase.Add(wordlist[place]);
  120. }
  121.  
  122. return string.Join(" ", lphrase);
  123. }
  124.  
  125. public static int Mod(int x, int m)
  126. {
  127. int r = x % m;
  128. return r < 0 ? r + m : r;
  129. }
  130. }
  131.  
  132. public class Crypto
  133. {
  134. private static readonly byte[] Salt = Encoding.ASCII.GetBytes("P&s$w0<rd__>_^*_M6n2g#r"); //todo: do something about this
  135.  
  136. public static string GenerateHash(string plaintext)
  137. {
  138. var plainText = Encoding.UTF8.GetBytes(plaintext);
  139. HashAlgorithm algorithm = new SHA256Managed();
  140.  
  141. var plainTextWithSaltBytes = new byte[plainText.Length + Salt.Length];
  142.  
  143. for (var i = 0; i < plainText.Length; i++)
  144. plainTextWithSaltBytes[i] = plainText[i];
  145.  
  146. for (var i = 0; i < Salt.Length; i++)
  147. plainTextWithSaltBytes[plainText.Length + i] = Salt[i];
  148.  
  149. return Convert.ToBase64String(algorithm.ComputeHash(plainTextWithSaltBytes));
  150. }
  151. public static string GenerateHashWithSeed(string plaintext, string salt)
  152. {
  153. HashAlgorithm algorithm = new SHA256Managed();
  154.  
  155. var plainText = Encoding.UTF8.GetBytes(plaintext);
  156. var saltBytes = Encoding.UTF8.GetBytes(salt);
  157. var plainTextWithSaltBytes = new byte[plainText.Length + saltBytes.Length];
  158.  
  159. for (var i = 0; i < plainText.Length; i++)
  160. plainTextWithSaltBytes[i] = plainText[i];
  161.  
  162. for (var i = 0; i < saltBytes.Length; i++)
  163. plainTextWithSaltBytes[plainText.Length + i] = saltBytes[i];
  164.  
  165. return Convert.ToBase64String(algorithm.ComputeHash(plainTextWithSaltBytes));
  166. }
  167. /// <summary>
  168. /// Encrypt the given string using AES. The string can be decrypted using
  169. /// DecryptStringAES(). The sharedSecret parameters must match.
  170. /// </summary>
  171. /// <param name="plainText">The text to encrypt.</param>
  172. /// <param name="sharedSecret">A password used to generate a key for encryption.</param>
  173. public static string EncryptStringAES(string plainText, string sharedSecret)
  174. {
  175. if (string.IsNullOrEmpty(plainText))
  176. throw new ArgumentNullException("plainText");
  177. if (string.IsNullOrEmpty(sharedSecret))
  178. throw new ArgumentNullException("sharedSecret");
  179.  
  180. string outStr; // encrypted string to return
  181.  
  182. try
  183. {
  184. // generate the key from the shared secret and the salt
  185. var key = new Rfc2898DeriveBytes(sharedSecret, Salt);
  186.  
  187. // Create a RijndaelManaged object
  188. var aesAlg = new RijndaelManaged();
  189. aesAlg.Key = key.GetBytes(aesAlg.KeySize/8);
  190.  
  191. // Create a decryptor to perform the stream transform.
  192. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
  193.  
  194. // Create the streams used for encryption.
  195. using (var msEncrypt = new MemoryStream())
  196. {
  197. // prepend the IV
  198. msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof (int));
  199. msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length);
  200.  
  201. using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
  202. using (var swEncrypt = new StreamWriter(csEncrypt))
  203. swEncrypt.Write(plainText); //Write all data to the stream.
  204.  
  205. outStr = Convert.ToBase64String(msEncrypt.ToArray());
  206. }
  207.  
  208. aesAlg.Clear();
  209. }
  210. catch (Exception ex)
  211. {
  212. Console.WriteLine("Error: {0}", ex);
  213. return "";
  214. }
  215.  
  216. // Return the encrypted bytes from the memory stream.
  217. return outStr;
  218. }
  219.  
  220. /// <summary>
  221. /// Decrypt the given string. Assumes the string was encrypted using
  222. /// EncryptStringAES(), using an identical sharedSecret.
  223. /// </summary>
  224. /// <param name="cipherText">The text to decrypt.</param>
  225. /// <param name="sharedSecret">A password used to generate a key for decryption.</param>
  226. public static string DecryptStringAES(string cipherText, string sharedSecret)
  227. {
  228. if (string.IsNullOrEmpty(cipherText))
  229. throw new ArgumentNullException("cipherText");
  230. if (string.IsNullOrEmpty(sharedSecret))
  231. throw new ArgumentNullException("sharedSecret");
  232.  
  233. // Declare the string used to hold
  234. // the decrypted text.
  235. string plaintext;
  236.  
  237. try
  238. {
  239. // generate the key from the shared secret and the salt
  240. var key = new Rfc2898DeriveBytes(sharedSecret, Salt);
  241.  
  242. // Create the streams used for decryption.
  243. var bytes = Convert.FromBase64String(cipherText);
  244.  
  245. using (var msDecrypt = new MemoryStream(bytes))
  246. {
  247. var aesAlg = new RijndaelManaged(); // Create a RijndaelManaged object with the specified key and IV.
  248. aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8);
  249.  
  250. // Get the initialization vector from the encrypted stream
  251. aesAlg.IV = ReadByteArray(msDecrypt);
  252.  
  253. // Create a decrytor to perform the stream transform.
  254. var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
  255.  
  256. using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
  257. using (var srDecrypt = new StreamReader(csDecrypt))
  258. plaintext = srDecrypt.ReadToEnd(); // Read the decrypted bytes from the decrypting stream and place them in a string.
  259.  
  260. aesAlg.Clear();
  261. }
  262. }
  263. catch (Exception ex)
  264. {
  265. Console.WriteLine("Error: {0}", ex);
  266. return "";
  267. }
  268.  
  269. return plaintext;
  270. }
  271.  
  272. private static byte[] ReadByteArray(Stream s)
  273. {
  274. var rawLength = new byte[sizeof(int)];
  275.  
  276. if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length)
  277. throw new SystemException("Stream did not contain properly formatted byte array");
  278.  
  279. var buffer = new byte[BitConverter.ToInt32(rawLength, 0)];
  280.  
  281. if (s.Read(buffer, 0, buffer.Length) != buffer.Length)
  282. throw new SystemException("Did not read byte array properly");
  283.  
  284. return buffer;
  285. }
  286. }
  287.  
  288. public class Profile
  289. {
  290. public string ProfileName;
  291. public bool LoggedIn = false;
  292. private Database.DBProfile _dbProfile;
  293. private string _phraseHash;
  294.  
  295. public Profile(Database.DBProfile dbProfile)
  296. {
  297. _dbProfile = dbProfile;
  298. ProfileName = _dbProfile.Name;
  299. }
  300.  
  301. public Database.Account AddAccount(string servicename, string username, string password)
  302. {
  303. // If password was generated by the program we don't need to save it, just the variables we can use to regenerate it
  304. var encryptedpassword = (password == null) ? null : Crypto.EncryptStringAES(password, _phraseHash);
  305.  
  306. var newAccount = new Database.Account(servicename, username, encryptedpassword); // Create account object
  307.  
  308. // Make sure profile does not already have an account with that name
  309. if (_dbProfile.Accounts.Any(a => (a.Username == username) && (a.ServiceName == servicename))) return null;
  310. // Add account to profile
  311. _dbProfile.Accounts.Add(newAccount); // Add account to profile objects list
  312. Database.SaveProfile(_dbProfile); // Save account in database
  313. return newAccount;
  314. }
  315.  
  316. public bool Login(string password)
  317. {
  318. var passwordHash = Crypto.GenerateHash(password); // Get password hash
  319. try
  320. {
  321. var encryptedphrasehash = Crypto.DecryptStringAES(_dbProfile.EncryptedPhraseHash, passwordHash); // Try to decrypt phrase with given password, throws if invalid
  322. _phraseHash = JsonConvert.DeserializeObject<Database.PhraseHashJson>(encryptedphrasehash).PhraseHash; // Get phrase hash from decrypted profile
  323. LoggedIn = true;
  324. return true;
  325. }
  326. catch (Exception) // Wrong password
  327. {
  328. return false;
  329. }
  330. }
  331.  
  332. public void Logout()
  333. {
  334. RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider();
  335. for (var i = 0; i < 3; i++)
  336. {
  337. byte[] data = new byte[(int) Math.Round((double) (_phraseHash.Count()))];
  338. rngCsp.GetBytes(data);
  339. int randomNum = BitConverter.ToInt32(data, 0);
  340. _phraseHash = randomNum.ToString();
  341. }
  342. LoggedIn = false;
  343. _phraseHash = null;
  344. }
  345.  
  346. public string GetAccountPassword(int accountIndex)
  347. {
  348. Database.Account account = _dbProfile.Accounts[accountIndex];
  349. // If encrypted password is null the password was generated with the program so we just re-generate it
  350. // If it isn't null the password was given by the user so we need to decrypt it
  351. return (account.EncryptedPassword == null)
  352. ? Crypto.GenerateHashWithSeed(account.ServiceName + account.Username, _phraseHash)
  353. : Crypto.DecryptStringAES(account.EncryptedPassword, _phraseHash);
  354. }
  355.  
  356. public void Delete()
  357. {
  358. if (LoggedIn) Logout(); // Erase phrase hash
  359. Database.DeleteProfile(ProfileName);
  360. }
  361.  
  362. public List<Database.Account> GetAccounts()
  363. {
  364. return _dbProfile.Accounts;
  365. }
  366.  
  367. public void DeleteAccount(int index)
  368. {
  369. var accountRemove = _dbProfile.Accounts[index];
  370. _dbProfile.Accounts.Remove(accountRemove);
  371. Database.SaveProfile(_dbProfile);
  372. }
  373. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement