Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portable Class Library (PCL) Contrib - Cryptography

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);
    }
}
like image 624
Muhammad Rehan Saeed Avatar asked Oct 02 '12 10:10

Muhammad Rehan Saeed


People also ask

How do I create a portable class library in xamarin?

Creating a PCL Start Visual Studio. Click File. Select New, then Project. Select the Class Library (Legacy Portable), as shown in Figure 1.

What is the difference between .NET Standard and PCL portable class libraries?

NET Standard is a set of curated APIs, picked by Microsoft, PCLS are not. The APIs that a PCL contains is dependent on the platforms that you choose to target when you create a PCL. This makes a PCL only sharable for the specific targets that you choose.

What is PCL in Visual Studio?

Portable Class Libraries (PCLs) are considered deprecated in the latest versions of Visual Studio. While you can still open, edit, and compile PCLs, for new projects it is recommended to use .


2 Answers

The docs are a little lacking, but I call this out in the FAQ:

Can I share the types from PclContrib with my platform-specific projects? No, not currently. While the types in PclContrib look and feel like their platform-specific counterparts, the runtime and compiler will see them as completely different types. While we have some ideas on how to make this work, this is a feature that we won't be looking at for the short term.

like image 121
David Kean Avatar answered Nov 08 '22 00:11

David Kean


The following .net code works on Desktop implementation. First add references to Portable.Desktop and 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); ;
    }
like image 24
user2959284 Avatar answered Nov 07 '22 23:11

user2959284