Add project files.
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
using Sarand.Net.Standard.Base.App;
|
||||
using Sarand.Net.Standard.Base.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Sarand.Net.Standard.Base.Data
|
||||
{
|
||||
//=======================================================================
|
||||
public static class SacsAesIvCrypter
|
||||
{
|
||||
//-------------------------------------------------------------------
|
||||
// Properties.
|
||||
public static String AesIvDelimiter { get; } = ";";
|
||||
public static String AesIvPrefix { get; } = "AESIV:";
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Ref. https://xamarinhelp.com/cryptography-in-xamarin-forms/
|
||||
// For reversible encryption, AES is generally the recommended standard.
|
||||
// AES 256 requires a 32 byte key to encrypt.
|
||||
// Either generate a 32 byte key or use any string and convert it into a key with CreateKey.
|
||||
// NB The salt will remain the same here for each key generated - it does not need to be randomized as with hashing.
|
||||
//-------------------------------------------------------------------
|
||||
private static byte[] CreateKey (string password, int keyBytes = 32)
|
||||
{
|
||||
byte[] salt = new byte[] { 80, 70, 60, 50, 40, 30, 20, 10 };
|
||||
int iterations = 300;
|
||||
DeriveBytes keyGenerator = new Rfc2898DeriveBytes(password, salt, iterations);
|
||||
return keyGenerator.GetBytes(keyBytes);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Encrypt String.
|
||||
// Return the encrypted text with the IV appended to the end.
|
||||
// In AES, the IV is a randomizer, making sure that no two identical messages ever give the same encrypted output.
|
||||
// The IV can be public and does not need to be hidden.
|
||||
//-------------------------------------------------------------------
|
||||
public static string Encrypt (this string clearValue, string encryptionKey)
|
||||
{
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = CreateKey(encryptionKey);
|
||||
byte[] aesIV = aes.IV;
|
||||
byte[] encrypted = Encrypt(clearValue, aes.Key, aesIV);
|
||||
return Convert.ToBase64String(encrypted) + AesIvDelimiter + Convert.ToBase64String(aesIV);
|
||||
}
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
public static byte[] Encrypt (string plainText, byte[] key, byte[] iv)
|
||||
{
|
||||
if (plainText == null || plainText.Length <= 0) throw new ArgumentNullException($"{nameof(plainText)}");
|
||||
if (key == null || key.Length <= 0) throw new ArgumentNullException($"{nameof(key)}");
|
||||
if (iv == null || iv.Length <= 0) throw new ArgumentNullException($"{nameof(iv)}");
|
||||
byte[] encrypted;
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = key;
|
||||
aes.IV = iv;
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
{
|
||||
using (ICryptoTransform encryptor = aes.CreateEncryptor())
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
|
||||
using (StreamWriter streamWriter = new StreamWriter(cryptoStream))
|
||||
{
|
||||
streamWriter.Write(plainText);
|
||||
}
|
||||
encrypted = memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Decrypt String.
|
||||
// Decryption requires the encrypted value and the secret key.
|
||||
// This function is directly related to the above encryption process and will
|
||||
// assume that the IV is at the end of the string passed in.
|
||||
// To decrypt a message encrypted by another function, the IV will have to be passed explicitly.
|
||||
//-------------------------------------------------------------------
|
||||
public static string Decrypt (this string encryptedValue, string encryptionKey)
|
||||
{
|
||||
String[] valueParts = encryptedValue.Split(new String[] { AesIvDelimiter }, StringSplitOptions.None);
|
||||
if (valueParts.Length != 2)
|
||||
{
|
||||
SaLogger.Warn("SacsAesIvCrypter.Decrypt Missing IV - assuming not encrypted");
|
||||
return encryptedValue;
|
||||
//throw new CryptographicException("Decrypt failure: Missing IV");
|
||||
}
|
||||
return Decrypt(Convert.FromBase64String(valueParts[0]), CreateKey(encryptionKey), Convert.FromBase64String(valueParts[1]));
|
||||
}
|
||||
//-------------------------------------------------------------------
|
||||
public static string Decrypt (byte[] cipherText, byte[] key, byte[] iv)
|
||||
{
|
||||
if (cipherText == null || cipherText.Length <= 0) throw new ArgumentNullException($"{nameof(cipherText)}");
|
||||
if (key == null || key.Length <= 0) throw new ArgumentNullException($"{nameof(key)}");
|
||||
if (iv == null || iv.Length <= 0) throw new ArgumentNullException($"{nameof(iv)}");
|
||||
|
||||
string plaintext = "";
|
||||
using (Aes aes = Aes.Create())
|
||||
{
|
||||
aes.Key = key;
|
||||
aes.IV = iv;
|
||||
using (MemoryStream memoryStream = new MemoryStream(cipherText))
|
||||
using (ICryptoTransform decryptor = aes.CreateDecryptor())
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
|
||||
using (StreamReader streamReader = new StreamReader(cryptoStream))
|
||||
plaintext = streamReader.ReadToEnd();
|
||||
}
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
}
|
||||
//=======================================================================
|
||||
}
|
||||
Reference in New Issue
Block a user