You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
7.3 KiB

  1. using System;
  2. using System.IO;
  3. using System.Security.Cryptography;
  4. using System.Text;
  5. namespace Swift.API.Common
  6. {
  7. public class EncryptDecryptUtility
  8. {
  9. protected static string saltValue = "K0r3@GM3";
  10. protected static string hashAlgorithm = "SHA1";
  11. protected static int passwordIterations = 5;
  12. protected static string initVector = "P@s$w0rDGm3KoR3@";
  13. protected static int keySize = 256;
  14. /// <summary>
  15. /// Encrypts specified plaintext using Rijndael symmetric key algorithm
  16. /// and returns a base64-encoded result.
  17. /// </summary>
  18. /// <param name="plainText">Plain Text to Encrypt</param>
  19. /// <param name="passPhrase">Pass Phrase to use in Password Generation</param>
  20. /// <returns>Encrypted text encoded into Base 64 text format </returns>
  21. public static string Encrypt(string plainText, string passPhrase)
  22. {
  23. // Convert strings into byte arrays.
  24. // Let us assume that strings only contain ASCII codes.
  25. // If strings include Unicode characters, use Unicode, UTF7, or UTF8
  26. // encoding.
  27. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
  28. byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
  29. // Convert our plaintext into a byte array.
  30. // Let us assume that plaintext contains UTF8-encoded characters.
  31. byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
  32. // First, we must create a password, from which the key will be derived.
  33. // This password will be generated from the specified passphrase and
  34. // salt value. The password will be created using the specified hash
  35. // algorithm. Password creation can be done in several iterations.
  36. var password = new PasswordDeriveBytes(
  37. passPhrase,
  38. saltValueBytes,
  39. hashAlgorithm,
  40. passwordIterations);
  41. // Use the password to generate pseudo-random bytes for the encryption
  42. // key. Specify the size of the key in bytes (instead of bits).
  43. #pragma warning disable 618, 612
  44. byte[] keyBytes = password.GetBytes(keySize / 8);
  45. #pragma warning restore 618, 612
  46. // Create uninitialized Rijndael encryption object.
  47. var symmetricKey = new RijndaelManaged();
  48. // It is reasonable to set encryption mode to Cipher Block Chaining
  49. // (CBC). Use default options for other symmetric key parameters.
  50. symmetricKey.Mode = CipherMode.CBC;
  51. // Generate encryptor from the existing key bytes and initialization
  52. // vector. Key size will be defined based on the number of the key
  53. // bytes.
  54. ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
  55. keyBytes,
  56. initVectorBytes);
  57. var memoryStream = new MemoryStream();
  58. // Define memory stream which will be used to hold encrypted data.
  59. var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
  60. // Start encrypting.
  61. cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
  62. // Finish encrypting.
  63. cryptoStream.FlushFinalBlock();
  64. // Convert our encrypted data from a memory stream into a byte array.
  65. byte[] cipherTextBytes = memoryStream.ToArray();
  66. // Close both streams.
  67. memoryStream.Close();
  68. cryptoStream.Close();
  69. // Convert encrypted data into a base64-encoded string.
  70. string cipherText = Convert.ToBase64String(cipherTextBytes);
  71. // Return encrypted string.
  72. return cipherText;
  73. }
  74. /// <summary>
  75. /// Decrypts specified cipherText using Rijndael symmetric key algorithm
  76. /// and returns a plain text result.
  77. /// </summary>
  78. /// <param name="cipherText">Encryted Text</param>
  79. /// <param name="passPhrase">Pass Phrase used in Password Generation</param>
  80. /// <returns></returns>
  81. public static string Decrypt(string cipherText, string passPhrase)
  82. {
  83. // Convert strings defining encryption key characteristics into byte
  84. // arrays. Let us assume that strings only contain ASCII codes.
  85. // If strings include Unicode characters, use Unicode, UTF7, or UTF8
  86. // encoding.
  87. byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
  88. byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);
  89. // Convert our ciphertext into a byte array.
  90. byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
  91. // First, we must create a password, from which the key will be
  92. // derived. This password will be generated from the specified
  93. // passphrase and salt value. The password will be created using
  94. // the specified hash algorithm. Password creation can be done in
  95. // several iterations.
  96. var password = new PasswordDeriveBytes(
  97. passPhrase,
  98. saltValueBytes,
  99. hashAlgorithm,
  100. passwordIterations);
  101. // Use the password to generate pseudo-random bytes for the encryption
  102. // key. Specify the size of the key in bytes (instead of bits).
  103. #pragma warning disable 618, 612
  104. byte[] keyBytes = password.GetBytes(keySize / 8);
  105. #pragma warning restore 618, 612
  106. // Create uninitialized Rijndael encryption object.
  107. var symmetricKey = new RijndaelManaged();
  108. // It is reasonable to set encryption mode to Cipher Block Chaining
  109. // (CBC). Use default options for other symmetric key parameters.
  110. symmetricKey.Mode = CipherMode.CBC;
  111. // Generate decryptor from the existing key bytes and initialization
  112. // vector. Key size will be defined based on the number of the key
  113. // bytes.
  114. ICryptoTransform decryptor = symmetricKey.CreateDecryptor(
  115. keyBytes,
  116. initVectorBytes);
  117. // Define memory stream which will be used to hold encrypted data.
  118. var memoryStream = new MemoryStream(cipherTextBytes);
  119. // Define cryptographic stream (always use Read mode for encryption).
  120. var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
  121. // Since at this point we don't know what the size of decrypted data
  122. // will be, allocate the buffer long enough to hold ciphertext;
  123. // plaintext is never longer than ciphertext.
  124. var plainTextBytes = new byte[cipherTextBytes.Length];
  125. // Start decrypting.
  126. int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
  127. // Close both streams.
  128. memoryStream.Close();
  129. cryptoStream.Close();
  130. // Convert decrypted data into a string.
  131. // Let us assume that the original plaintext string was UTF8-encoded.
  132. string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
  133. // Return decrypted string.
  134. return plainText;
  135. }
  136. }
  137. }