2012-10-02 7 views
5

私はPortable Class Library Contrib project on codeplexで暗号を使用したいが、どのように私がそれを使うことができるかのドキュメントは見つかっていない。ポータブルクラスライブラリ(PCL)寄稿者 - 暗号

EncryptDecryptのメソッドを含むラッパークラスを作成したいと思います。このラッパークラスを移植可能なクラスライブラリにしたいと思います。私はPortable.RuntimePortable.Security.Cryptographyをこのプロジェクトで参照しました。これは正しいです?

私は、.NET、Windows Phone、Metroプロジェクトの中で自分のラッパーを使いたいと思っています。これらのプロジェクトでは、ラッパープロジェクトPortable.Runtime,Portable.Security.Cryptographyおよび対応するポータブルプロジェクト、つまりPortable.Desktop,Portable.PhoneまたはPortable.WindowsStoreを参照しています。これは正しいです?

ただし、ラッパークラスを使用しようとすると、矛盾する名前空間エラーが発生します。これはエラーと私のラッパークラスです:

タイプSystem.Security.Cryptography.AesManagedC:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.Core.dllC:\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); 
    } 
} 
+1

への参照を追加します。それとも残りの質問がありますか?そうであれば、明示的に述べるべきです。 – CodesInChaos

+1

btwあなたのIV使用が悪いです。 IVは、実行する暗号化ごとに異なる必要があります。 – CodesInChaos

答えて

1

の両方に存在することは、暗号化アルゴリズムのための私の一般的なラッパーが問題を引き起こしていたことが判明しました。 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 
} 
+0

この機能を使用して数行の例を含めることはできますか? –

+0

私はまた、Windows Phone 8とWindowsストアの両方のアプリケーションを提供するためにpcl-contrib暗号を使用しようとしています。 、SymmetricAlgorithm、新しい().... ' ので、私はそれの非ジェネリックバージョンを作成することができます は、だから私は、質問 からあなたのコードをコピーしていたし、「密封された」削除Tはそれから 'パブリッククラスSymmetricCryptography あなたが提案したように。 これを使用してソリューションのどこかに投稿してください。 –

+0

'this.provider.KeySize'を使用しましたが、プロバイダはSymmetricAlgorithmであり、KeySizeはありませんか? –

3

は、ドキュメントが欠けて少しですが、私はFAQでこれを呼び出す:

Iからタイプを共有することができます私のプラットフォーム固有のプロジェクトでPclContrib?いいえ、現在はありません。 PclContribのlookと の型は、それぞれのプラットフォーム固有のものと同じように感じますが、ランタイムと コンパイラでは完全に異なる型として表示されます。我々は この作品を作る方法に関するいくつかのアイデアを持っているが、これは我々が短期的に見ているだろう しない機能です。

2

以下の.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); ; 
    }