2012-10-02 14 views
5

Chcę korzystać z kryptografii w Portable Class Library Contrib project on codeplex, ale nie znalazłem żadnej dokumentacji, w jaki sposób mogę z niej korzystać.Przenośna biblioteka klas (PCL) Contrib - Kryptografia

Chcę utworzyć wewnątrz klasy metody otoki z Encrypt i Decrypt i chcę, aby ta klasa otoki istniała w przenośnej bibliotece klas. Wymieniłem w tym projekcie Portable.Runtime i Portable.Security.Cryptography. Czy to jest poprawne?

Następnie chcę użyć mojego opakowania wewnątrz projektu .NET, Windows Phone i Metro. W tych projektach odwołuję się do mojego projektu opakowania, Portable.Runtime, Portable.Security.Cryptography i odpowiedniego projektu przenośnego, tj. Portable.Desktop, Portable.Phone lub Portable.WindowsStore. Czy to jest poprawne?

Dostaję sprzeczne błędy przestrzeni nazw, gdy próbuję użyć mojej klasy opakowania. Jest to błąd i moja klasa wrapper:

Typ System.Security.Cryptography.AesManaged istnieje zarówno C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\Profile\Client\System.Core.dll i 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); 
    } 
} 
+1

Jeśli rozwiązać problem, odpowiedzieć na rozwiązanie jako odpowiedź, zamiast edytowania go na to pytanie. Czy masz jeszcze jakieś pytania? Jeśli tak, powinieneś je wyraźnie podać. – CodesInChaos

+1

przy użyciu IV jest złe. Wartość IV powinna być inna dla każdego wykonywanego szyfrowania. – CodesInChaos

Odpowiedz

1

Okazuje się, że mój generic wrapper dla algorytmów kryptograficznych było przyczyną problemu. PCL Contrib zawiera klasę o nazwie SymmetricAlgorithm, która sama jest opakowaniem dla prawdziwego algorytmu SymmetricAlgorithm. Jeśli zrobię moja klasa wrapper nierodzajową to działa tak:

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

Czy można również podać przykład kilku linii za pomocą tych funkcji? –

+0

Próbuję również użyć kryptografii pcl-contrib do obsługi aplikacji Windows 8 i Windows Store. Więc zrobiłem skopiować kod z pytaniem i usunięte "zamknięte" z niego 'public class SymmetricCryptography gdzie T: SymmetricAlgorithm, new() ....' więc mogę utworzyć non rodzajowego wersję tego, jak sugerujesz. Czy mógłbyś zamieścić gdzieś rozwiązanie z tego powodu? –

+0

Użyłeś 'this.provider.KeySize', ale dostawca jest SymmetricAlgorithm i nie ma KeySize? –

3

docs są trochę brakuje, ale ja nazywam to uwagę w FAQ:

Mogę udostępnić typy od PclContrib z moimi projektami specyficznymi dla platformy? Nie, obecnie nie. Podczas gdy typy w PclContrib wyglądają jak i ich odpowiedniki dla platformy, to środowisko wykonawcze i kompilator postrzegają je jako zupełnie różne typy. Chociaż mamy kilka pomysłów, jak to zrobić, jest to funkcja, której nie będziemy oglądać przez krótki czas.

2

Następujący kod .net działa na implementacji Desktop. Pierwszy dodać referencje do Portable.Desktop i 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); ; 
    } 
Powiązane problemy