Question

I am trying to use to implement AES CTR encryption using the Bouncy castle cryptography library in C#. .NET provides RijndaelManaged Crypto Library but it does not support CTR mode for AES hence the selection of Bouncycastle.

I haven't been able to code it properly The problem seems to be with IV.

    public string BytesToHex(byte[] bytes)
    {
        char[] c = new char[bytes.Length * 2];

        byte b;

        for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
        {
            b = ((byte)(bytes[bx] >> 4));
            c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);

            b = ((byte)(bytes[bx] & 0x0F));
            c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
        }

        return new string(c);
    }

    public byte[] HexToBytes(string str)
    {
        if (str.Length == 0 || str.Length % 2 != 0)
            return new byte[0];

        byte[] buffer = new byte[str.Length / 2];
        char c;
        for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
        {
            // Convert first half of byte
            c = str[sx];
            buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);

            // Convert second half of byte
            c = str[++sx];
            buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
        }

        return buffer;
    }
   private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
    {
        int minSize = cipher.GetOutputSize(data.Length);
        byte[] outBuf = new byte[minSize];
        int length1 = cipher.ProcessBytes(data, 0, data.Length, outBuf, 0);
        int length2 = cipher.DoFinal(outBuf, length1);
        int actualLength = length1 + length2;
        byte[] result = new byte[actualLength];
        Array.Copy(outBuf,result,actualLength);

        //System.arraycopy(outBuf, 0, result, 0, result.length);
        return result;
    }
    private static byte[] decryptCTR(byte[] cipher, byte[] key, byte[] iv)
    {
        //Org.BouncyCastle.Crypto.Modes.SicBlockCipher

      PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(new AesEngine()));

      ParametersWithIV   ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
      aes.Init(false, ivAndKey);

      return cipherData(aes, cipher);
    }
    private static byte[] encryptCTR(byte[] plain, byte[] key, byte[] iv)
    {
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new SicBlockCipher(
                new AesEngine()));

        ParametersWithIV ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
        aes.Init(true, ivAndKey);
        return cipherData(aes, plain);
    }

And I am trying to decrypt a given cipher text using the following method

   private void btnDecryptDirectly_Click(object sender, EventArgs e)
    {
        String encodedMsgHex =  "770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451";
        String key = "36f18357be4dbd77f050515c73fcf9f2";
        byte [] keyBytes = HexToBytes(key);

        byte[] cipher = HexToBytes(encodedMsgHex);

        txtDecryptedText = BytesToHex(decryptCTR(cipher, keyBytes, IV));

        rtbDecrypted.Text = txtDecryptedText;
    }

Every time I run this I get error the

last block incomplete in decryption

Error.

Can any one please help me out.

Was it helpful?

Solution

You don't need to use PaddedBufferedBlockCipher at all. Counter mode encryption is a streaming mode for a block cipher. Streaming ciphers don't need padding.

You can use BufferedBlockCipher to access the streaming mode as SicBlockCipher only lets you encrypt one block at a time.

OTHER TIPS

If you need just CTR mode, you can easily code it by yourself - it just writing IV, IV + 1, IV + 2, IV +3 ... to buffer (up to input data size), encrypting this buffer, and xoring with buffer you need to encrypt or decrypt. This can be achieved with builtin Rijndael Managed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top