[英]Portable Class Library (PCL) Contrib - Cryptography
我想在codeplex上的Portable Class Library Contrib项目中使用加密,但是没有找到关于如何使用它的任何文档。
我想在其中创建一个包含Encrypt
和Decrypt
方法的包装类,我希望这个包装类存在于可移植类库中。 我在这个项目中引用了Portable.Runtime
和Portable.Security.Cryptography
。 它是否正确?
然后我想在.NET,Windows Phone和Metro项目中使用我的包装器。 在这些项目中,我引用了我的包装器项目, Portable.Runtime
, Portable.Security.Cryptography
和相应的Portable项目,即Portable.Desktop
, Portable.Phone
或Portable.WindowsStore
。 它是否正确?
但是当我尝试使用我的包装器类时,我遇到了冲突的命名空间错误。 这是错误和我的包装类:
System.Security.Cryptography.AesManaged
类型存在于C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0\\Profile\\Client\\System.Core.dll
和C:\\Downloads\\PclContrib\\bin\\Debug\\Portable.Security.Cryptography.dll
public sealed class SymmetricCryptography<T> where T : SymmetricAlgorithm, new()
{
private readonly T provider = new T();
private readonly UTF8Encoding utf8 = new UTF8Encoding();
private byte[] key;
private byte[] iv;
public byte[] Key
{
get { return this.key; }
}
public byte[] IV
{
get { return this.iv; }
}
public SymmetricCryptography()
{
this.key = this.provider.Key;
this.iv = this.provider.IV;
}
public SymmetricCryptography(byte[] key, byte[] iv)
{
this.key = key;
this.iv = iv;
}
public SymmetricCryptography(string password, string salt)
{
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, this.utf8.GetBytes(salt));
this.key = deriveBytes.GetBytes(this.provider.KeySize >> 3);
this.iv = deriveBytes.GetBytes(16);
}
public SymmetricCryptography(string password, string salt, int iterations)
{
Rfc2898DeriveBytes deriveBytes = new Rfc2898DeriveBytes(password, this.utf8.GetBytes(salt), iterations);
this.key = deriveBytes.GetBytes(this.provider.KeySize >> 3);
this.iv = deriveBytes.GetBytes(16);
}
public byte[] Encrypt(byte[] input)
{
return this.Encrypt(input, this.key, this.iv);
}
public byte[] Encrypt(byte[] input, byte[] key, byte[] iv)
{
return this.Transform(
input,
this.provider.CreateEncryptor(key, iv));
}
public byte[] Decrypt(byte[] input)
{
return this.Decrypt(input, this.key, this.iv);
}
public byte[] Decrypt(byte[] input, byte[] key, byte[] iv)
{
return this.Transform(
input,
this.provider.CreateDecryptor(key, iv));
}
public string Encrypt(string text)
{
return this.Encrypt(text, this.key, this.iv);
}
public string Encrypt(string text, byte[] key, byte[] iv)
{
byte[] output = this.Transform(
this.utf8.GetBytes(text),
this.provider.CreateEncryptor(key, iv));
return Convert.ToBase64String(output);
}
public string Decrypt(string text)
{
return this.Decrypt(text, this.key, this.iv);
}
public string Decrypt(string text, byte[] key, byte[] iv)
{
byte[] output = this.Transform(
Convert.FromBase64String(text),
this.provider.CreateDecryptor(key, iv));
return this.utf8.GetString(output, 0, output.Length);
}
public void Encrypt(Stream input, Stream output)
{
this.Encrypt(input, output, this.key, this.iv);
}
public void Encrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
this.TransformStream(true, ref input, ref output, key, iv);
}
public void Decrypt(Stream input, Stream output)
{
this.Decrypt(input, output, this.key, this.iv);
}
public void Decrypt(Stream input, Stream output, byte[] key, byte[] iv)
{
this.TransformStream(false, ref input, ref output, key, iv);
}
private byte[] Transform(
byte[] input,
ICryptoTransform cryptoTransform)
{
byte[] result;
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptStream = new CryptoStream(
memoryStream,
cryptoTransform,
CryptoStreamMode.Write))
{
cryptStream.Write(input, 0, input.Length);
cryptStream.FlushFinalBlock();
memoryStream.Position = 0;
result = memoryStream.ToArray();
}
}
return result;
}
private void TransformStream(bool encrypt, ref Stream input, ref Stream output, byte[] key, byte[] iv)
{
// defensive argument checking
if (input == null)
{
throw new ArgumentNullException("input");
}
if (output == null)
{
throw new ArgumentNullException("output");
}
if (!input.CanRead)
{
throw new ArgumentException("Unable to read from the input Stream.", "input");
}
if (!output.CanWrite)
{
throw new ArgumentException("Unable to write to the output Stream.", "output");
}
// make the buffer just large enough for
// the portion of the stream to be processed
byte[] inputBuffer = new byte[input.Length - input.Position];
// read the stream into the buffer
input.Read(inputBuffer, 0, inputBuffer.Length);
// transform the buffer
byte[] outputBuffer = encrypt ? Encrypt(inputBuffer, key, iv)
: Decrypt(inputBuffer, key, iv);
// write the transformed buffer to our output stream
output.Write(outputBuffer, 0, outputBuffer.Length);
}
}
文档有点缺乏,但我在常见问题中称之为:
我可以与我的平台特定项目共享PclContrib中的类型吗? 不,不是。 虽然PclContrib中的类型看起来和感觉像是特定于平台的对应物,但运行时和编译器会将它们视为完全不同的类型。 虽然我们对如何使这项工作有一些想法,但这是我们短期内不会考虑的功能。
以下.net代码适用于桌面实现。 首先添加对Portable.Desktop和Portable.Security.Cryptography.ProtectedData的引用
private void button2_Click(object sender, EventArgs e)
{
String encrypted = PCL.CentralClass.Encrypt("yo");
String decreypted = PCL.CentralClass.Decrypt(encrypted);
//PCL.CentralClass.
}
//https://pclcontrib.codeplex.com/documentation?FocusElement=Comment
//\Source\Portable.Security.Cryptography.ProtectedData\Security\Cryptography\ProtectedData.cs
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
static string GetString(byte[] bytes)
{
char[] chars = new char[bytes.Length / sizeof(char)];
System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
return new string(chars);
}
public static String Encrypt(String strEncrypt)
{
byte[] userData = GetBytes(strEncrypt);
byte[] optionalEntropy = null;
byte[] x = System.Security.Cryptography.ProtectedData.Protect(userData, optionalEntropy);
return GetString(x);
}
public static String Decrypt(String strDecrypt)
{
byte[] encryptedData = GetBytes(strDecrypt);
byte[] optionalEntropy = null;
byte[] x = System.Security.Cryptography.ProtectedData.Unprotect(encryptedData, optionalEntropy);
return GetString(x); ;
}
事实证明,我的密码算法的通用包装器导致了一个问题。 PCL Contrib包含一个名为SymmetricAlgorithm的类,它本身就是真正的SymmetricAlgorithm的包装器。 如果我使我的包装类非泛型它的工作方式如下:
public sealed class AesManagedSymmetricCryptography : SymmetricCryptography<AesManaged>
{
#region Constructors
public AesManagedSymmetricCryptography()
{
}
public AesManagedSymmetricCryptography(byte[] key, byte[] iv)
: base(key, iv)
{
}
public AesManagedSymmetricCryptography(string password, string salt)
: base(password, salt)
{
}
public AesManagedSymmetricCryptography(string password, string salt, int iterations)
: base(password, salt, iterations)
{
}
#endregion
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.