Advertisement
Guest User

Untitled

a guest
Dec 9th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.45 KB | None | 0 0
  1. const int _saltSize = 48; // 16 is often recommended, better safe than sorry
  2. const int _keySize = 48;
  3. const int _iterations = 1048576; // maybe randomize + store?
  4.  
  5. private static byte[] Hash(string password, int iterations, byte[] salt = null)
  6. {
  7. var pass = password.ToBytes();
  8. var saltAndHash = new byte[0];
  9.  
  10. if (salt == null) // if encrypting, store salt
  11. {
  12. salt = new CryptoRandom().NextBytes(_saltSize);
  13. saltAndHash = Utils.Combine(saltAndHash, salt);
  14. }
  15.  
  16. int blockSize = 8; // maybe 16 with less iterations considering modern GPUs?
  17. int parallel = 1;
  18. return Utils.Combine(saltAndHash, SCrypt.ComputeDerivedKey(pass, salt, iterations, blockSize, parallel, null, _keySize));
  19. }
  20.  
  21. internal static void SaveMasterKey(Keyring k, string password, string file)
  22. {
  23. // Keyring is simply holding the session keys in CngKey props
  24.  
  25. var hashed = Hash(password, _iterations);
  26. var saltSegment = new ArraySegment<byte>(hashed, 0, _saltSize);
  27. var passSegment = new ArraySegment<byte>(hashed, _saltSize, _keySize);
  28. var blob = k.SenderDHM.GetPrivateBlob();
  29.  
  30. using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
  31. {
  32. fs.Write(saltSegment.ToArray(), 0, _saltSize);
  33. using (var etm = new EtM_EncryptTransform(passSegment.ToArray(), saltSegment))
  34. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))
  35. cs.Write(blob, 0, blob.Length);
  36. }
  37. }
  38.  
  39. internal static Keyring LoadMasterKey(string password, string file)
  40. {
  41. var salt = new byte[_saltSize];
  42. Keyring k = new Keyring();
  43.  
  44. using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
  45. {
  46. fs.Read(salt, 0, _saltSize);
  47. var hashed = Hash(password, _iterations, salt);
  48. if (Authenticate(file, hashed, salt))
  49. {
  50. using (var etm = new EtM_DecryptTransform(hashed, salt.AsArraySegment()))
  51. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
  52. {
  53. byte[] blob = new byte[152];
  54. cs.Read(blob, 0, blob.Length);
  55. k.SenderDHM = blob.ToPrivateKeyFromBlob();
  56. }
  57. }
  58. }
  59. return k;
  60. }
  61.  
  62. private static bool Authenticate(string file, byte[] key, byte[] salt)
  63. {
  64. using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
  65. using (var etm = new EtM_DecryptTransform(key, salt.AsArraySegment(), authenticateOnly: true))
  66. {
  67. fs.Position = salt.Length;
  68. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read)) cs.CopyTo(Stream.Null);
  69. if (!etm.IsComplete) throw new Exception("Authentication failed.");
  70. }
  71. return true;
  72. }
  73.  
  74. internal static void EncryptText(string text, Keyring k, string file, bool forSender)
  75. {
  76. SharedEphemeralBundle ephemeralBundle;
  77. if (forSender) ephemeralBundle = k.SenderDHM.GetSharedEphemeralDhmSecret();
  78. else ephemeralBundle = k.ReceiverDHM.GetSharedEphemeralDhmSecret();
  79.  
  80. var ephemeralPublic = ephemeralBundle.EphemeralDhmPublicKeyBlob;
  81. var ephemeralSymmetric = ephemeralBundle.SharedSecret;
  82. var textBytes = text.ToBytes();
  83.  
  84. using (var fs = new FileStream(file, FileMode.Create, FileAccess.Write))
  85. {
  86. fs.Write(ephemeralPublic, 0, ephemeralPublic.Length);
  87. using (var etm = new EtM_EncryptTransform(ephemeralSymmetric))
  88. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Write))
  89. cs.Write(textBytes, 0, textBytes.Length);
  90. }
  91. }
  92.  
  93. internal static string DecryptText(string file, Keyring k)
  94. {
  95. string decrypted = null;
  96. var ephemeralPublic = new byte[104];
  97.  
  98. using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
  99. {
  100. fs.Read(ephemeralPublic, 0, 104);
  101. var ephemeralSymmetric = k.SenderDHM.GetSharedDhmSecret(ephemeralPublic.ToPublicKeyFromBlob());
  102. if (Authenticate(file, ephemeralSymmetric, 104))
  103. {
  104. using (var etm = new EtM_DecryptTransform(ephemeralSymmetric))
  105. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read))
  106. {
  107. var decrypt = new byte[fs.Length - 104];
  108. cs.Read(decrypt, 0, decrypt.Length);
  109. decrypted = decrypt.FromBytes();
  110. }
  111. }
  112. }
  113. return decrypted;
  114. }
  115.  
  116. // overloading the above similar
  117. private static bool Authenticate(string file, byte[] key, int offset)
  118. {
  119. using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read))
  120. using (var etm = new EtM_DecryptTransform(key, authenticateOnly: true))
  121. {
  122. fs.Position = offset;
  123. using (var cs = new CryptoStream(fs, etm, CryptoStreamMode.Read)) cs.CopyTo(Stream.Null);
  124. if (!etm.IsComplete) throw new Exception("Authentication failed.");
  125. }
  126. return true;
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement