-1

I am getting the following error while decrypting the content using AesCryptoServiceProvider. The mode which I need to use is CipherMode.CFB and PaddingMode is PKCS7. I am able to decrypt the same content in iOS with same key, IV, PaddingMode and Cipher Mode.

I tried to use CryptoStream in the following way but not able to decrypt the content.

public byte[] DecryptWithAES(byte[] content, byte[] key, byte[] iv, int mode, int paddingMode)
{
    byte[] plainBytes = null;
    using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
    {
        aes.BlockSize = 128;
        aes.KeySize = 256;

        aes.IV = iv;
        aes.Key = key;

        aes.Padding = (PaddingMode)paddingMode;
        aes.Mode = (CipherMode)mode;

        ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
        using (var input = new MemoryStream(content))
        {
            using (var output = new MemoryStream())
            {
                using (var cryptStream = new CryptoStream(input, crypto, CryptoStreamMode.Read))
                {
                    var buffer = new byte[1024];
                    var read = cryptStream.Read(buffer, 0, buffer.Length);
                    while (read > 0)
                    {
                        output.Write(buffer, 0, read);
                        read = cryptStream.Read(buffer, 0, buffer.Length);
                    }
                }

                    plainBytes = output.ToArray();
            }
        }

        return plainBytes;
    }
}

I also tried following way to decrypt the content but not working,

public byte[] DecryptWithAES(byte[] content, byte[] key, byte[] iv, int mode, int paddingMode)
{
    byte[] plainBytes = null;
    using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
    {
        aes.BlockSize = 128;
        aes.KeySize = 256;

        aes.IV = iv;
        aes.Key = key;

        aes.Padding = (PaddingMode)paddingMode;
        aes.Mode = (CipherMode)mode;

        ICryptoTransform crypto = aes.CreateDecryptor(aes.Key, aes.IV);
        plainBytes = crypto.TransformFinalBlock(content, 0, content.Length);
    }

    return plainBytes;
}

In both cases, the Padding Mode is PKCS7 and CipherMode is CFB.

I tried this on the encrypted content of length 22. Key Length: 32, IV Length: 16.

I am stuck with this problem from yesterday. Please help me.

Pravin Patil
  • 418
  • 5
  • 23
  • 2
    PKCS7 never produces output size 22. Post the encryption code, it's probably broken. Also, you can't flush a cryptostream. You must dispose it before being able to use the output. Correct the code and update it here. – usr Mar 14 '16 at 11:50
  • I also tried other Padding Mode like None and Zeros. Actually the IOS app uses None padding. I am getting the exception before calling cryptStream.Flush(). – Pravin Patil Mar 14 '16 at 11:59
  • `Actually the IOS app uses None padding` and it works. That's more evidence that the encryption code messes up the padding. Post the encryption code as asked. Voting to close for now because answer is not possible. – usr Mar 14 '16 at 12:09
  • The encryption code is written in Java service and I don't have the code for it. But the iOS application and one more python client is able to decrypt the content. – Pravin Patil Mar 14 '16 at 12:14
  • Then maybe you don't have the right settings. Using no padding with AES is not really possible. It should result in garbage bytes at the end of the decrypted data. I don't understand how they can even produce a 22 byte output. It should be a multiple of 16 bytes. One of your assumptions is wrong. – usr Mar 14 '16 at 12:16
  • @usr It is possible to encrypt data with AES without padding by using CTR mode. – zaph Mar 14 '16 at 12:28
  • @zaph true, but it can't be CTR mode here because that would not decrypt at all with these settings. .NET has no CTR support. – usr Mar 14 '16 at 12:28
  • @usr Note that CFB mode can be used as a stream cypher, see [Cipher Feedback](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher_Feedback_.28CFB.29) since the plain text is xor'ed with the output of the encryption in a similar fashion to CTR mode. Depending on the implementation of CFB mode the input does not need to be a multiple of the block size. – zaph Mar 14 '16 at 12:39
  • Last time I checked .NET did not support any stream-like mode with block ciphers (which I found annoying). Therefore, CFB should not be supported. Or, I overlooked something. I really wonder why none of that is supported since it obviates the need for padding and it's associated troubles. – usr Mar 14 '16 at 12:41
  • @usr It is possible that another library other than AesManaged is being used. Consider the developer specifically wanted to use CFB, he would have to use another library. Consider the OP states that CFB mode is used and that there are 22-bytes of encrypted data which is consistent with CFB mode. Also iOS Common Crypto does support CFB mode albeit not in the one-shot function. – zaph Mar 14 '16 at 12:48
  • Could .NET with differing settings approximately decode CFB or CTR? Clearly, the settings have to match for correct decryption but maybe he is seeing mostly correct decryption with some garbled bytes at the end. – usr Mar 14 '16 at 12:50
  • yes, iOS application is using kCCModeOptionCTR_BE to decrypt the content. – Pravin Patil Mar 14 '16 at 12:56
  • @zaph I guess you're right :) Maybe it kind of works here because it's just two blocks and the first one might be identical for CTR and what he's using. – usr Mar 14 '16 at 13:19
  • Thanks. It will not be possible to use CBC with padding since this is a already establish product. I will try out CTR mode in .Net. – Pravin Patil Mar 14 '16 at 15:20

2 Answers2

0

Finally I ended up using Bouncy castle library and above content is decrypted using "AES/CFB/NoPadding". No CTR mode required to decrypt the content.

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

private byte[] Decrypt(byte[] content, byte[] key, byte[] iv, string mode)
        {

            var cipher = CipherUtilities.GetCipher(mode);
            cipher.Init(false, new ParametersWithIV(new KeyParameter(key), iv));
            var blockBytes = cipher.ProcessBytes(content, 0, content.Length);
            var finalBytes = cipher.DoFinal();

            var plainBytes = new byte[content.Length];

            var counter = 0;
            if (blockBytes != null)
            {
                for (var i = 0; i < blockBytes.Length; i++)
                    plainBytes[counter++] = blockBytes[i];
            }

            if (finalBytes != null)
            {
                for (var i = 0; i < finalBytes.Length; i++)
                    plainBytes[counter++] = finalBytes[i];
            }

            return plainBytes;
        }
Pravin Patil
  • 418
  • 5
  • 23
-1

Try

encrypted = encrypted.Replace(" ", "+");
BionicCode
  • 1
  • 4
  • 28
  • 44
Wowo Ot
  • 1,362
  • 13
  • 21