EP 0.1.1 Symbolization
This commit is contained in:
208
Convention/[Runtime]/EasySave/EasySaveCrypto.cs
Normal file
208
Convention/[Runtime]/EasySave/EasySaveCrypto.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
#if !DISABLE_ENCRYPTION
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
#if NETFX_CORE
|
||||
using Windows.Security.Cryptography;
|
||||
using Windows.Security.Cryptography.Core;
|
||||
using Windows.Storage.Streams;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
#endif
|
||||
|
||||
namespace Convention.EasySave.Internal
|
||||
{
|
||||
public static class EasySaveHash
|
||||
{
|
||||
#if NETFX_CORE
|
||||
public static string SHA1Hash(string input)
|
||||
{
|
||||
return System.Text.Encoding.UTF8.GetString(UnityEngine.Windows.Crypto.ComputeSHA1Hash(System.Text.Encoding.UTF8.GetBytes(input)));
|
||||
}
|
||||
#else
|
||||
public static string SHA1Hash(string input)
|
||||
{
|
||||
using (SHA1Managed sha1 = new SHA1Managed())
|
||||
return System.Text.Encoding.UTF8.GetString(sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(input)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public abstract class EncryptionAlgorithm
|
||||
{
|
||||
public abstract byte[] Encrypt(byte[] bytes, string password, int bufferSize);
|
||||
public abstract byte[] Decrypt(byte[] bytes, string password, int bufferSize);
|
||||
public abstract void Encrypt(Stream input, Stream output, string password, int bufferSize);
|
||||
public abstract void Decrypt(Stream input, Stream output, string password, int bufferSize);
|
||||
|
||||
protected static void CopyStream(Stream input, Stream output, int bufferSize)
|
||||
{
|
||||
byte[] buffer = new byte[bufferSize];
|
||||
int read;
|
||||
while ((read = input.Read(buffer, 0, bufferSize)) > 0)
|
||||
output.Write(buffer, 0, read);
|
||||
}
|
||||
}
|
||||
|
||||
public class AESEncryptionAlgorithm : EncryptionAlgorithm
|
||||
{
|
||||
private const int ivSize = 16;
|
||||
private const int keySize = 16;
|
||||
private const int pwIterations = 100;
|
||||
|
||||
public override byte[] Encrypt(byte[] bytes, string password, int bufferSize)
|
||||
{
|
||||
using (var input = new MemoryStream(bytes))
|
||||
{
|
||||
using (var output = new MemoryStream())
|
||||
{
|
||||
Encrypt(input, output, password, bufferSize);
|
||||
return output.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override byte[] Decrypt(byte[] bytes, string password, int bufferSize)
|
||||
{
|
||||
using (var input = new MemoryStream(bytes))
|
||||
{
|
||||
using (var output = new MemoryStream())
|
||||
{
|
||||
Decrypt(input, output, password, bufferSize);
|
||||
return output.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Encrypt(Stream input, Stream output, string password, int bufferSize)
|
||||
{
|
||||
input.Position = 0;
|
||||
|
||||
#if NETFX_CORE
|
||||
// Generate an IV and write it to the output.
|
||||
var iv = CryptographicBuffer.GenerateRandom(ivSize);
|
||||
output.Write(iv.ToArray(), 0, ivSize);
|
||||
|
||||
var pwBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
|
||||
var keyDerivationProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm("PBKDF2_SHA1");
|
||||
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(iv, pwIterations);
|
||||
// Create a key based on original key and derivation parmaters
|
||||
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
|
||||
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, keySize);
|
||||
|
||||
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
|
||||
var key = provider.CreateSymmetricKey(keyMaterial);
|
||||
|
||||
// Get the input stream as an IBuffer.
|
||||
IBuffer msg;
|
||||
using(var ms = new MemoryStream())
|
||||
{
|
||||
input.CopyTo(ms);
|
||||
msg = ms.ToArray().AsBuffer();
|
||||
}
|
||||
|
||||
var buffEncrypt = CryptographicEngine.Encrypt(key, msg, iv);
|
||||
|
||||
|
||||
output.Write(buffEncrypt.ToArray(), 0, (int)buffEncrypt.Length);
|
||||
output.Dispose();
|
||||
#else
|
||||
using (var alg = Aes.Create())
|
||||
{
|
||||
alg.Mode = CipherMode.CBC;
|
||||
alg.Padding = PaddingMode.PKCS7;
|
||||
alg.GenerateIV();
|
||||
var key = new Rfc2898DeriveBytes(password, alg.IV, pwIterations);
|
||||
alg.Key = key.GetBytes(keySize);
|
||||
// Write the IV to the output stream.
|
||||
output.Write(alg.IV, 0, ivSize);
|
||||
using(var encryptor = alg.CreateEncryptor())
|
||||
using(var cs = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
|
||||
CopyStream(input, cs, bufferSize);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Decrypt(Stream input, Stream output, string password, int bufferSize)
|
||||
{
|
||||
#if NETFX_CORE
|
||||
var thisIV = new byte[ivSize];
|
||||
input.Read(thisIV, 0, ivSize);
|
||||
var iv = thisIV.AsBuffer();
|
||||
|
||||
var pwBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
|
||||
|
||||
var keyDerivationProvider = KeyDerivationAlgorithmProvider.OpenAlgorithm("PBKDF2_SHA1");
|
||||
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(iv, pwIterations);
|
||||
// Create a key based on original key and derivation parameters.
|
||||
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
|
||||
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, keySize);
|
||||
|
||||
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
|
||||
var key = provider.CreateSymmetricKey(keyMaterial);
|
||||
|
||||
// Get the input stream as an IBuffer.
|
||||
IBuffer msg;
|
||||
using(var ms = new MemoryStream())
|
||||
{
|
||||
input.CopyTo(ms);
|
||||
msg = ms.ToArray().AsBuffer();
|
||||
}
|
||||
|
||||
var buffDecrypt = CryptographicEngine.Decrypt(key, msg, iv);
|
||||
|
||||
output.Write(buffDecrypt.ToArray(), 0, (int)buffDecrypt.Length);
|
||||
#else
|
||||
using (var alg = Aes.Create())
|
||||
{
|
||||
var thisIV = new byte[ivSize];
|
||||
input.Read(thisIV, 0, ivSize);
|
||||
alg.IV = thisIV;
|
||||
|
||||
var key = new Rfc2898DeriveBytes(password, alg.IV, pwIterations);
|
||||
alg.Key = key.GetBytes(keySize);
|
||||
|
||||
using(var decryptor = alg.CreateDecryptor())
|
||||
using(var cryptoStream = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
|
||||
CopyStream(cryptoStream, output, bufferSize);
|
||||
|
||||
}
|
||||
#endif
|
||||
output.Position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class UnbufferedCryptoStream : MemoryStream
|
||||
{
|
||||
private readonly Stream stream;
|
||||
private readonly bool isReadStream;
|
||||
private string password;
|
||||
private int bufferSize;
|
||||
private EncryptionAlgorithm alg;
|
||||
private bool disposed = false;
|
||||
|
||||
public UnbufferedCryptoStream(Stream stream, bool isReadStream, string password, int bufferSize, EncryptionAlgorithm alg) : base()
|
||||
{
|
||||
this.stream = stream;
|
||||
this.isReadStream = isReadStream;
|
||||
this.password = password;
|
||||
this.bufferSize = bufferSize;
|
||||
this.alg = alg;
|
||||
|
||||
|
||||
if (isReadStream)
|
||||
alg.Decrypt(stream, this, password, bufferSize);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
disposed = true;
|
||||
|
||||
if (!isReadStream)
|
||||
alg.Encrypt(this, stream, password, bufferSize);
|
||||
stream.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user