Search code examples
c#encryptionwindows-8

System.Security.Cryptography vs. Windows.Security.Cryptography


I am a new Windows 8 developer, I have some code that was designed for Linux but also ran on Windows as long as GTK# was installed.

I am currently porting that application to Windows 8 as a Modern UI (Metro) app. It is going well, except, when I try to import my key derivation code (which takes the user's password and derives a key 256 bit key from it), Visual Studio Ultimate 2013 indicates that it doesn't recognize using System.Security.Cryptography.

After looking into the Windows 8 developer website, I found that a new class, Windows.Security.Cryptography is available, however, it doesn't seem to be recognized by Visual Studio either.

So, now that you have the background, I have a few questions:

  1. Is System.Security.Cryptography available in Windows 8? If so, is the RT version supported? How can I make Visual Studio recognize it?
  2. How is Windows.System.Security different, and is there a compatible class/method to Rfc2898DeriveBytes? By compatible, I mean given the same password and salt is there a way to get the same key as a result.

For clarification as to what I want to do, my key derivation code is posted below:

public class GetKey
{
    // constructor
    public GetKey (bool use=true, string password="none")
    {   if (use == true)
        {
            this.genSalt();
            byte[] salt = this.salt;
            Rfc2898DeriveBytes pwdKey = new Rfc2898DeriveBytes(password, salt, 4000);
            this.key = pwdKey.GetBytes(32);
            this.iv = pwdKey.GetBytes(16);
        }
    }

    // properties
    private byte[] key;
    private byte[] iv;
    private byte[] salt;

    // methods
    public void retrieveKey(string password)
    {
        try 
        {
            byte[] salt = this.salt;
            Rfc2898DeriveBytes pwdKey = new Rfc2898DeriveBytes(password, salt, 4000);
            this.key = pwdKey.GetBytes(32);
            this.iv = pwdKey.GetBytes(16);
        }
        catch (Exception e)
        {
            GenericDialog win = new GenericDialog("Unknown Error: " + e.Message, "Error Notice", "Unknown Error");
            win.Show();
        }
    }

    public void genSalt()
    {
        string sSalt = UtilityClass.randString(16);
        byte[] salt = UtilityClass.ToByteArray(sSalt);
        this.salt = salt;
    }   

    public byte[] returnKey()
    {
        return this.key;
    }

    public byte[] returnIv()
    {
        return this.iv;
    }

    public byte[] returnSalt()
    {
        return this.salt;
    }
    public bool setSalt(string salt)
    {
        try 
        {
            this.salt = Convert.FromBase64String(salt);
        }
        catch
        {
            GenericDialog win = new GenericDialog("Decryption failed because the salt was invalid.", "Error Notice", "Invalid Salt");
            win.Show();
            return false;
        }
        return true;
    }
}

Solution

  • The Windows.Security.Cryptography and its sub-namespaces are probably the way to go.

    See http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.cryptography.core.cryptographicengine.derivekeymaterial.aspx for a way to derive key material using a couple of various algorithms.