The following forum(s) have migrated to Microsoft Q&A (Preview): Developing Universal Windows apps!
Visit Microsoft Q&A (Preview) to post new questions.

Learn More

 locked
[W8.1]Encryption/Decryption with Salt/IV RRS feed

  • Question

  • I've been ask to do a task in a project that involves encryption on a windows 8.

    The scenario is something like this:

    I get a byte[] from a server, the first 16 bytes are the IV, the next 128 are the Salt and the remaining ones are the File itself.

    The user then provides a password and with that and the salt i should create a PKCS5 Key with 40 iterations and the key should have 32bits length.

    Right now i've splitted the byte[] in th 3 i require, but i dont know how the rest is done in windows C#.

    Tuesday, October 6, 2015 2:40 PM

All replies

  • Hi Thought2,

    Looks like there is no supported API for PKCS#5 algorithm in WinRT app. See here about supported algorithm names.

    But you can use the following way to make it work:

    public class Encrypt
    {
                public static byte[] aesCbcPkcs5(byte[] message, byte[] key, byte[] iv)
                {
                    SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7); // PKCS5
                    IBuffer buffKey = CryptographicBuffer.CreateFromByteArray(key);
                    CryptographicKey ckey = objAlg.CreateSymmetricKey(buffKey);
    
    
                    IBuffer buffPlaintext = CryptographicBuffer.CreateFromByteArray(message);
                    IBuffer buffIV = CryptographicBuffer.CreateFromByteArray(iv);
                    IBuffer buffEncrypt = CryptographicEngine.Encrypt(ckey, buffPlaintext, buffIV);
    
                    byte[] ret;
                    CryptographicBuffer.CopyToByteArray(buffEncrypt, out ret);
    
                    return ret;
                }
    
    }
    
    public class Decrypt
    {
                public static byte[] aesCbcPkcs5(byte[] message, byte[] key, byte[] iv)
                {
                    SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
                    IBuffer buffKey = CryptographicBuffer.CreateFromByteArray(key);
                    CryptographicKey ckey = objAlg.CreateSymmetricKey(buffKey);
    
    
                    IBuffer buffPlaintext = CryptographicBuffer.CreateFromByteArray(message);
                    IBuffer buffIV = CryptographicBuffer.CreateFromByteArray(iv);
                    IBuffer buffEncrypt = CryptographicEngine.Decrypt(ckey, buffPlaintext, buffIV);
    
                    byte[] ret;
                    CryptographicBuffer.CopyToByteArray(buffEncrypt, out ret);
                    return ret;
                }
    
    }


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, October 7, 2015 11:24 AM
  • Thanks for the help.

    From what im seeing in your code, you would have to know the key in advance to do those operations.

    what i have is:

    byte[1024] data  // this is filled with data from server

    from data[0] to data[15] is my IV

    from data[16] to data[144] is my Salt (128 bytes)

    Password is a string provided by a user.

    to uses those methods i need to create a Key, in my case it should be a PKCS5 key created with 40 iterations.

    i say something like this in another post, but im not sure where i define that it should be PKCS5

    public static void GenerateKeyMaterial2(string password, string salt, uint iterationCount, out IBuffer keyMaterial, out IBuffer iv)
            {
                // Setup KDF parameters for the desired salt and iteration count
                IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
                KeyDerivationParameters kdfParameters = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, iterationCount);
    
                // Get a KDF provider for PBKDF2, and store the source password in a Cryptographic Key
                KeyDerivationAlgorithmProvider kdf = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
                IBuffer passwordBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
                CryptographicKey passwordSourceKey = kdf.CreateKey(passwordBuffer);
    
                // Generate key material from the source password, salt, and iteration count.  Only call DeriveKeyMaterial once,
                // since calling it twice will generate the same data for the key and IV.
                int keySize = 256 / 8;
                int initVectorSize = 128 / 8;
                uint totalDataNeeded = (uint)(keySize + initVectorSize);
                IBuffer keyAndIv = CryptographicEngine.DeriveKeyMaterial(passwordSourceKey, kdfParameters, totalDataNeeded);
    
                // Split the derived bytes into a seperate key and IV
                byte[] keyMaterialBytes = keyAndIv.ToArray();
                keyMaterial = WindowsRuntimeBuffer.Create(keyMaterialBytes, 0, keySize, keySize);
                iv = WindowsRuntimeBuffer.Create(keyMaterialBytes, keySize, initVectorSize, initVectorSize);
            }

    • Edited by Thought2 Wednesday, October 7, 2015 2:41 PM
    Wednesday, October 7, 2015 2:39 PM
  • Hi Thought2,

    >>i say something like this in another post, but im not sure where i define that it should be PKCS5

    Ref my last reply, you need to change this part:

    // Get a KDF provider for PBKDF2, and store the source password in a Cryptographic Key
    KeyDerivationAlgorithmProvider kdf = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
    IBuffer passwordBuffer = CryptographicBuffer.ConvertStringToBinary(password, BinaryStringEncoding.Utf8);
    CryptographicKey passwordSourceKey = kdf.CreateKey(passwordBuffer);

    to

    SymmetricKeyAlgorithmProvider objAlg = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7); // PKCS5
    IBuffer passwordBuffer = CryptographicBuffer.CreateFromByteArray(key);
    CryptographicKey passwordSourceKey = objAlg.CreateSymmetricKey(passwordBuffer);
    


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, October 20, 2015 7:42 AM