locked
CryptographicEngine.DecryptAsync - InvalidCastException

    Question

  • Hi,

    when I was trying to decrypt some file in WinRT I have stumbled upon some odd behaviour. DecryptAsync method throws InvalidCastException but synchronous Decrypt runs just fine. I'm not sure if this is a known bug or if I am doing something wrong.

    I was able to reproduce the issue with this simplified example:

    private async void CryptoTest()
    {
        IBuffer ivBuffer = GetByteSequence(16);
        IBuffer keyBuffer = GetByteSequence(32);            
        IBuffer plainData = GetByteSequence(128);

        SymmetricKeyAlgorithmProvider provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
        CryptographicKey key = provider.CreateSymmetricKey(keyBuffer);
        var encryptedData = CryptographicEngine.Encrypt(key, plainData, ivBuffer);

        try
        {
            //This runs just fine
            var decryptedData = CryptographicEngine.Decrypt(key, encryptedData, ivBuffer);
                    
            //This throws: System.InvalidCastException
            var asyncDecryptedData = await CryptographicEngine.DecryptAsync(key, encryptedData, ivBuffer);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            Debug.WriteLine(ex.ToString());
        }
    }

    CreateByteSequence creates simple dummy data:

    private IBuffer GetByteSequence(int length)
    {
        byte[] iv = new byte[length];
    
        for (int i = 0; i < length; i++)
            iv[i] = (byte)(length % 256);
    
        return CryptographicBuffer.CreateFromByteArray(iv);
    }

    I've tested it on Windows 8.1, Visual Studio 2013, Update 2

    Thanks for reply in advance.

    Thursday, June 19, 2014 10:13 AM

Answers

  • This is expected behavior. The symmetric key decryption is already fast and so doesn't need to be done asynchronously. You only need (and can) call DecryptAsync on persisted keys.

    From the DecryptAsync docs:

    If the key is a persisted key and the decrypt operation requires UI or takes a long time, use the DecryptAsync method instead of the Decrypt method. For example, UI is required when decrypting using a key that is strongly protected.

    --Rob

    Thursday, June 26, 2014 1:39 AM
    Owner

All replies

  • Hi Matej,

    I can also reproduce the issue you are facing, I will fire this to seniors to see if this could be a bug or something wrong with the API usage.

    As I understand, if a non-async method works fine, its async method should be ok too, the async is only used to forbid non-UI interaction.

    Please be patient and it may take few days. Thanks for your understanding and thanks for reporting this issue to us.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Friday, June 20, 2014 1:31 AM
    Moderator
  • This is expected behavior. The symmetric key decryption is already fast and so doesn't need to be done asynchronously. You only need (and can) call DecryptAsync on persisted keys.

    From the DecryptAsync docs:

    If the key is a persisted key and the decrypt operation requires UI or takes a long time, use the DecryptAsync method instead of the Decrypt method. For example, UI is required when decrypting using a key that is strongly protected.

    --Rob

    Thursday, June 26, 2014 1:39 AM
    Owner
  • Hi Rob,

    thanks for your answer, though I must say this can't really be called expected behavior. When API wants to tell me I can't call async version of one of its fuctions, then InvalidCastException is a not the best choice of exception to throw.

    I was dealing with encrypted files of unspecified size (usually about 10 - 30 MB). I have read the documentation you mentioned and after the part "takes a long time" I decided Async version would be more suitable. Of course after running into trouble I triple checked my Key, IV, Encryption mode,... the last thing I tried was the non-async version :)

    Now that I think about it, nowhere in docs does it say I cant use the Async version whenever I want. I would expect Sync and Async versions to return the same result, albeit with worse performance.

    The docs even encourage me to use it: if (false && false || true) go for async; :-D

    Wednesday, July 16, 2014 9:33 PM