using System.Security.Cryptography; using System.Text; using Nop.Core; using Nop.Core.Domain.Security; namespace Nop.Services.Security; /// /// Encryption service /// public partial class EncryptionService : IEncryptionService { #region Fields protected readonly SecuritySettings _securitySettings; #endregion #region Ctor public EncryptionService(SecuritySettings securitySettings) { _securitySettings = securitySettings; } #endregion #region Utilities /// /// Encrypt text /// /// Text to encrypt /// Encryption algorithm /// Encrypted data protected static byte[] EncryptTextToMemory(string data, SymmetricAlgorithm provider) { using var ms = new MemoryStream(); using (var cs = new CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write)) { var toEncrypt = Encoding.Unicode.GetBytes(data); cs.Write(toEncrypt, 0, toEncrypt.Length); cs.FlushFinalBlock(); } return ms.ToArray(); } /// /// Decrypt text /// /// Encrypted data /// Encryption algorithm /// Decrypted text protected static string DecryptTextFromMemory(byte[] data, SymmetricAlgorithm provider) { using var ms = new MemoryStream(data); using var cs = new CryptoStream(ms, provider.CreateDecryptor(), CryptoStreamMode.Read); using var sr = new StreamReader(cs, Encoding.Unicode); return sr.ReadToEnd(); } /// /// Gets encryption algorithm /// /// Encryption key /// Encryption algorithm protected virtual SymmetricAlgorithm GetEncryptionAlgorithm(string encryptionKey) { ArgumentException.ThrowIfNullOrEmpty(encryptionKey); SymmetricAlgorithm provider = _securitySettings.UseAesEncryptionAlgorithm ? Aes.Create() : TripleDES.Create(); var vectorBlockSize = provider.BlockSize / 8; provider.Key = Encoding.ASCII.GetBytes(encryptionKey[0..16]); provider.IV = Encoding.ASCII.GetBytes(encryptionKey[^vectorBlockSize..]); return provider; } #endregion #region Methods /// /// Create salt key /// /// Key size /// Salt key public virtual string CreateSaltKey(int size) { //generate a cryptographic random number using var provider = RandomNumberGenerator.Create(); var buff = new byte[size]; provider.GetBytes(buff); // Return a Base64 string representation of the random number return Convert.ToBase64String(buff); } /// /// Create a password hash /// /// Password /// Salk key /// Password format (hash algorithm) /// Password hash public virtual string CreatePasswordHash(string password, string saltkey, string passwordFormat) { return HashHelper.CreateHash(Encoding.UTF8.GetBytes(string.Concat(password, saltkey)), passwordFormat); } /// /// Encrypt text /// /// Text to encrypt /// Encryption private key /// Encrypted text public virtual string EncryptText(string plainText, string encryptionPrivateKey = "") { if (string.IsNullOrEmpty(plainText)) return plainText; if (string.IsNullOrEmpty(encryptionPrivateKey)) encryptionPrivateKey = _securitySettings.EncryptionKey; using var provider = GetEncryptionAlgorithm(encryptionPrivateKey); var encryptedBinary = EncryptTextToMemory(plainText, provider); return Convert.ToBase64String(encryptedBinary); } /// /// Decrypt text /// /// Text to decrypt /// Encryption private key /// Decrypted text public virtual string DecryptText(string cipherText, string encryptionPrivateKey = "") { if (string.IsNullOrEmpty(cipherText)) return cipherText; if (string.IsNullOrEmpty(encryptionPrivateKey)) encryptionPrivateKey = _securitySettings.EncryptionKey; using var provider = GetEncryptionAlgorithm(encryptionPrivateKey); var buffer = Convert.FromBase64String(cipherText); return DecryptTextFromMemory(buffer, provider); } #endregion }