便携式类库(PCL)的Contrib - 密码学 [英] Portable Class Library (PCL) Contrib - Cryptography

查看:199
本文介绍了便携式类库(PCL)的Contrib - 密码学的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用的加密在可移植类库项目的Contrib在codePLEX 但还没有找到如何,我可以使用它的任何文件。

我想创建一个加密解密里面方法的封装类,我想这个包装类存在于便携式类库。我曾经引用 Portable.Runtime Portable.Security.Cryptography 在这个项目。这是正确的?

然后,我想用我的包装一个.NET,Windows手机和地铁项目中。在这些项目中,我引用我的包装项目, Portable.Runtime Portable.Security.Cryptography 和相应的便携式项目即 Portable.Desktop Portable.Phone Portable.WindowsStore 。这是正确的?

当我尝试但是用我的包装类,我得到冲突的命名空间的错误。这是错误,我的包装类:

  

类型 System.Security.Cryptography.AesManaged 同时存在于 C:\ Program Files文件(x86)的\参考大会\微软\框架\ .NETFramework \ V4.0 \档案\客户端\ System.Core.dll的 C:\下载\ PclContrib \斌\调试\ Portable.Security.Cryptography.dll

 公共密封类SymmetricCryptography< T>其中T:SymmetricAlgorithm,新的()
{
    私人只读牛逼商=新T();
    私人只读UTF8Encoding UTF8 =新UTF8Encoding();

    私人字节[]键;
    私人字节[] IV;

    公共字节[]键
    {
        {返回this.key; }
    }

    公共字节[] IV
    {
        {返回this.iv; }
    }

    公共SymmetricCryptography()
    {
        this.key = this.provider.Key;
        this.iv = this.provider.IV;
    }

    公共SymmetricCryptography(字节[]键,byte []的IV)
    {
        this.key =键;
        四this.iv =;
    }

    公共SymmetricCryptography(字符串密码,串盐)
    {
        Rfc2898DeriveBytes deriveBytes =新Rfc2898DeriveBytes(密码,this.utf8.GetBytes(盐));
        this.key = deriveBytes.GetBytes(this.provider.KeySize>→3);
        this.iv = deriveBytes.GetBytes(16);
    }

    公共SymmetricCryptography(字符串密码,串盐,INT迭代)
    {
        Rfc2898DeriveBytes deriveBytes =新Rfc2898DeriveBytes(密码,this.utf8.GetBytes(盐),次迭代);
        this.key = deriveBytes.GetBytes(this.provider.KeySize>→3);
        this.iv = deriveBytes.GetBytes(16);
    }

    公共byte []的加密(byte []的输入)
    {
        返回this.Encrypt(输入,this.key,this.iv);
    }

    公共byte []的加密(byte []的输入,字节[]键,byte []的IV)
    {
        返回this.Transform(
            输入,
            this.provider.CreateEncryptor(键,IV));
    }

    公共字节[]解密(byte []的输入)
    {
        返回this.Decrypt(输入,this.key,this.iv);
    }

    公共字节[]解密(byte []的输入,字节[]键,byte []的IV)
    {
        返回this.Transform(
            输入,
            this.provider.CreateDecryptor(键,IV));
    }

    公共字符串加密(字符串文本)
    {
        返回this.Encrypt(文字,this.key,this.iv);
    }

    公共字符串加密(字符串文本,字节[]键,byte []的IV)
    {
        byte []的输出= this.Transform(
            this.utf8.GetBytes(文字),
            this.provider.CreateEncryptor(键,IV));
        返回Convert.ToBase64String(输出);
    }

    公共字符串解密(文本字符串)
    {
        返回this.Decrypt(文字,this.key,this.iv);
    }

    公共字符串解密(字符串文本,字节[]键,byte []的IV)
    {
        byte []的输出= this.Transform(
            Convert.FromBase64String(文字),
            this.provider.CreateDecryptor(键,IV));
        返回this.utf8.GetString(输出,0,output.Length);
    }

    公共无效加密(流输入,流输出)
    {
        this.Encrypt(输入,输出,this.key,this.iv);
    }

    公共无效加密(流输入,流输出,字节[]键,byte []的IV)
    {
        this.TransformStream(真,参考输入,参考输出,键,IV);
    }

    公共无效解密(流输入,流输出)
    {
        this.Decrypt(输入,输出,this.key,this.iv);
    }

    公共无效解密(流输入,流输出,字节[]键,byte []的IV)
    {
        this.TransformStream(假,参考输入,参考输出,键,IV);
    }

    私人byte []的变换(
        byte []的输入,
        ICryptoTransform的cryptoTransform)
    {
        byte []的结果;

        使用(MemoryStream的MemoryStream的=新的MemoryStream())
        {
            使用(CryptoStream的cryptStream =新的CryptoStream(
                MemoryStream的,
                cryptoTransform,
                CryptoStreamMode.Write))
            {
                cryptStream.Write(输入,0,input.Length);
                cryptStream.FlushFinalBlock();
                memoryStream.Position = 0;
                结果= memoryStream.ToArray();
            }
        }

        返回结果;
    }

    私人无效TransformStream(布尔加密,裁判流输入,裁判流输出,字节[]键,byte []的IV)
    {
        //防守参数检查
        如果(输入== NULL)
        {
            抛出新ArgumentNullException(输入);
        }

        如果(输出== NULL)
        {
            抛出新ArgumentNullException(输出);
        }

        如果(!input.CanRead)
        {
            抛出新的ArgumentException(无法从输入流中读取,输入);
        }

        如果(!output.CanWrite)
        {
            抛出新的ArgumentException(无法写入到输出流,输出);
        }

        //使缓冲区刚好够大
        //流的一部分被处理
        byte []的INPUTBUFFER =新的字节[input.Length  -  input.Position]。
        //读取流入缓冲区
        input.Read(INPUTBUFFER,0,inputBuffer.Length);
        //改造缓冲区
        byte []的OUTPUTBUFFER =加密?加密(INPUTBUFFER,钥匙,四)
                                        :解密(INPUTBUFFER,钥匙,四);
        //写入转​​换缓冲器输出流
        output.Write(OUTPUTBUFFER,0,outputBuffer.Length);
    }
}
 

解决方案

事实证明,我的通用包装的加密算法是导致问题。 PCL的Contrib中含有一类称为SymmetricAlgorithm这本身就是一个包装,真正的SymmetricAlgorithm。如果我让我的包装类非通用它的工作原理是这样的:

 公共密封类AesManagedSymmetricCryptography:SymmetricCryptography< AesManaged>
{
    #区域构造

    公共AesManagedSymmetricCryptography()
    {
    }

    公共AesManagedSymmetricCryptography(字节[]键,byte []的IV)
        :基地(重点,IV)
    {
    }

    公共AesManagedSymmetricCryptography(字符串密码,串盐)
        :基地(口令,盐)
    {
    }

    公共AesManagedSymmetricCryptography(字符串密码,串盐,INT迭代)
        :基座(密码,盐,迭代)
    {
    }

    #endregion
}
 

I want to use the cryptography in the Portable Class Library Contrib project on codeplex but have not found any documentation on how I can use it.

I want to create a wrapper class with Encrypt and Decrypt methods inside it and I want this wrapper class to exist in a portable class library. I have referenced Portable.Runtime and Portable.Security.Cryptography in this project. Is this correct?

I then want to use my wrapper inside a .NET, Windows Phone and Metro project. In these projects I reference my wrapper project, Portable.Runtime, Portable.Security.Cryptography and the corresponding Portable project i.e. Portable.Desktop, Portable.Phone or Portable.WindowsStore. Is this correct?

I get conflicting namespace errors when I try to use my wrapper class however. This is the error and my wrapper class:

The type System.Security.Cryptography.AesManaged exists in both C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.Core.dll and 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);
    }
}

解决方案

It turns out that my generic wrapper for the cryptography algorithms was causing a problem. PCL Contrib contains a class called SymmetricAlgorithm which is itself a wrapper for the real SymmetricAlgorithm. If I make my wrapper class non-generic it works like this:

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
}

这篇关于便携式类库(PCL)的Contrib - 密码学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆