diff --git a/Interfaces/IXCipher.cs b/Interfaces/IXCipher.cs new file mode 100644 index 0000000..f7857a1 --- /dev/null +++ b/Interfaces/IXCipher.cs @@ -0,0 +1,10 @@ +namespace xCommons.Interfaces +{ + public interface IXCipher + { + string Encrypt(string plainText); + string Decrypt(string cipherText); + string EncryptFromBytes(byte[] textBytes); + string DecryptFromBytes(byte[] cipherBytes); + } +} \ No newline at end of file diff --git a/Providers/XCipher.cs b/Providers/XCipher.cs new file mode 100644 index 0000000..83fd142 --- /dev/null +++ b/Providers/XCipher.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using xCommons.Extensions; +using xCommons.Interfaces; + +namespace xCommons.Providers +{ + public class XCipher : IXCipher + { + // + #region Props ... + private readonly string secretKey; + private readonly byte[] iv; + private readonly byte[] key; + private readonly XValidationProvider validationProvider; + #endregion + + // + #region Constructor ... + public XCipher( + string cipherKey, + XValidationProvider validationProvider + ) + { + // + this.secretKey = cipherKey.ToMd5String(); + this.validationProvider = validationProvider; + + // + var ivBytes = new byte[16]; + var keyBytes = new byte[32]; + var secretBytes = Encoding.UTF8.GetBytes(this.secretKey); + + // + Array.Copy( + secretBytes, + ivBytes, + secretBytes.Length < ivBytes.Length ? + secretBytes.Length : + ivBytes.Length + ); + this.iv = ivBytes; + + // + Array.Copy( + secretBytes, + keyBytes, + secretBytes.Length < keyBytes.Length ? + secretBytes.Length : + keyBytes.Length + ); + this.key = keyBytes; + + // Encoding.UTF8.GetBytes (this.secretKey); + } + #endregion + + // + #region Actions ... + public string Encrypt(string plainText) + { + // + validationProvider.NotEmpty(plainText); + + // + var textBytes = Encoding.UTF8.GetBytes(plainText); + var result = EncryptFromBytes(textBytes); + + // + return result; + } + + public string Decrypt(string cipherText) + { + // + validationProvider.NotEmpty(cipherText); + + // + var cipherBytes = Convert.FromBase64String(cipherText); + var result = DecryptFromBytes(cipherBytes); + + // + return result; + } + + public string EncryptFromBytes(byte[] textBytes) + { + // + // Validate Args ... + validationProvider.NotNull(textBytes); + + // Declare the string used to hold + // the decrypted text. + byte[] encryptedBytes = null; + + // Create an RijndaelManaged object + // with the specified key and IV. + using (var rijAlg = new RijndaelManaged()) + { + //Settings + rijAlg.Mode = CipherMode.CBC; + rijAlg.Padding = PaddingMode.PKCS7; + // rijAlg.FeedbackSize = 128; + + rijAlg.Key = key; + rijAlg.IV = iv; + + // + using (var encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV)) + { + encryptedBytes = encryptor.TransformFinalBlock(textBytes, 0, textBytes.Length); + } + } + + // + return Convert.ToBase64String(encryptedBytes); + } + + public string DecryptFromBytes(byte[] cipherBytes) + { + // + // Validate Args ... + validationProvider.NotNull(cipherBytes); + + // Declare the string used to hold + // the decrypted text. + string plaintext = null; + + // Create an RijndaelManaged object + // with the specified key and IV. + using (var rijAlg = new RijndaelManaged()) + { + //Settings + rijAlg.Mode = CipherMode.CBC; + rijAlg.Padding = PaddingMode.PKCS7; + // rijAlg.FeedbackSize = 128; + + rijAlg.Key = key; + rijAlg.IV = iv; + + // Create a decrytor to perform the stream transform. + var decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV); + + // Create the streams used for decryption. + using (var msDecrypt = new MemoryStream(cipherBytes)) + { + using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) + { + using (var srDecrypt = new StreamReader(csDecrypt)) + { + // Read the decrypted bytes from the decrypting stream + // and place them in a string. + plaintext = srDecrypt.ReadToEnd(); + } + } + } + } + + // + return plaintext; + } + #endregion + } +} \ No newline at end of file