20

I am using the "BouncyCastle.Crypto.dll" for encrypt/decrypt a string in my app. I am using the following code from this blog:

  1. I have a class BCEngine, exactly the same as the one given in the link mentioned above.

    public class BCEngine
    {
       private readonly Encoding _encoding;
       private readonly IBlockCipher _blockCipher;
       private PaddedBufferedBlockCipher _cipher;
       private IBlockCipherPadding _padding;
    
       public BCEngine(IBlockCipher blockCipher, Encoding encoding)
       {
          _blockCipher = blockCipher;
          _encoding = encoding;
       }
    
       public void SetPadding(IBlockCipherPadding padding)
       {
           if (padding != null)
             _padding = padding;
       }
    
       public string Encrypt(string plain, string key)
       {
           byte[] result = BouncyCastleCrypto(true, _encoding.GetBytes(plain), key);
           return Convert.ToBase64String(result);
       }
    
       public string Decrypt(string cipher, string key)
       {
          byte[] result = BouncyCastleCrypto(false, Convert.FromBase64String(cipher), key);
          return _encoding.GetString(result);
       }
    
       /// <summary>
       ///
       /// </summary>
       /// <param name="forEncrypt"></param>
       /// <param name="input"></param>
       /// <param name="key"></param>
       /// <returns></returns>
       /// <exception cref="CryptoException"></exception>
       private byte[] BouncyCastleCrypto(bool forEncrypt, byte[] input, string key)
       {
           try
           {
               _cipher = _padding == null ? new PaddedBufferedBlockCipher(_blockCipher) : new PaddedBufferedBlockCipher(_blockCipher, _padding);
               byte[] keyByte = _encoding.GetBytes(key);
               _cipher.Init(forEncrypt, new KeyParameter(keyByte));
               return _cipher.DoFinal(input);
           }
           catch (Org.BouncyCastle.Crypto.CryptoException ex)
           {
               throw new CryptoException(ex.Message);
           }
       }
    }
    

I am using an asp.net form in which i have written code as given below:

    public partial class EncryptionForm : System.Web.UI.Page
    {
      Encoding _encoding;
      IBlockCipherPadding _padding;
      string key = "DFGFRT";
       string textToBeEncrypted = "Original text. Please encrypt me.";
       string txtEncryptedText = string.empty;
       string txtDecryptedText = string.empty;

      protected void Page_Load(object sender, EventArgs e)
      {
          _encoding = Encoding.ASCII; 
          Pkcs7Padding pkcs = new Pkcs7Padding();
          _padding = pkcs;   
      }

      protected void btnEncrypt_Click(object sender, EventArgs e)
      {
          txtEncryptedText = AESEncryption(textToBeEncrypted, key, true);
      }

      protected void btnDecrypt_Click(object sender, EventArgs e)
      {
          txtDecryptedText = AESDecryption(txtEncryptedText.Text, key, true);
      }

      public string AESEncryption(string plain, string key, bool fips)
      {
          BCEngine bcEngine = new BCEngine(new AesEngine(), _encoding);
          bcEngine.SetPadding(_padding);
          return bcEngine.Encrypt(plain, key);
      }

      public string AESDecryption(string cipher, string key, bool fips)
      {
          BCEngine bcEngine = new BCEngine(new AesEngine(), _encoding);
          bcEngine.SetPadding(_padding);
          return bcEngine.Decrypt(cipher, key);
      }
    }

Not sure, but due to some reason, I get an exception when I call the btnEncrypt_Click

"Key length not 128/192/256 bits."

Can anybody please guide? I am a complete newbie to this. Thanks in Advance.

Octopoid
  • 3,507
  • 5
  • 22
  • 43
Hari
  • 477
  • 1
  • 9
  • 20
  • Hi Hari, I'm also busy developing pgp messaging in my android app with c#. I hope you can help me with something. Could we connect somehow? – Yaza Jan 14 '22 at 14:05

3 Answers3

9

Your string key = "DFGFRT"; is not 128/192/256 bits.

DFGFRT is 6 characters, which is 6 (or 12?) bytes = 8*12 = 96 bits (at most).

To get a 128 bit key you need a 16 byte string, so I'd go on the safe side and use a 16 character string so it will be a 128 bit key if using single byte characters and 256 if using wide characters.

jgauffin
  • 99,844
  • 45
  • 235
  • 372
Matt
  • 7,100
  • 3
  • 28
  • 58
  • I have got one more question: I have been asked to use a six byte(48 bits) key, something like "ABCDEF" for decryption. How to use this key so that it is treated as 128/192/256 bits. Has it got something to do with padding. If yes, how can I handle it? Thanks in advance again. – Hari May 06 '11 at 11:49
  • 48 bits is not big enough. You should only use 256 bit keys or larger for security reasons. What you want to do is not advised, even if it was possible, there is one possible solution which I won't provide. – Security Hound May 06 '11 at 12:25
  • If you have been asked to use a six byte key then you'll have to change the key before you can use it with bouncy castle. The simplest way is just pad it with a given character to be the right number of bytes. – Matt May 06 '11 at 12:40
5

Fairly simple, your key is "DFGFRT" which is 6 characters/bytes, which is 6 * 8 = 48 bits.

The encryption methods used needs a key of 128/192/256 bits in length, which equals to 16/24/32 characters/bytes.

Roger Far
  • 2,178
  • 3
  • 36
  • 67
  • @jgauffin, did you edit my answer or Rogier21s? I have an edit on mine and he has a comment saying you edited it. – Matt May 06 '11 at 11:19
  • I edited both. Yours to make it more readable and his to change bytes to bits. – jgauffin May 06 '11 at 11:21
0

public class AesGcm256 { private static readonly SecureRandom Random = new SecureRandom();

    // Pre-configured Encryption Parameters
    public static readonly int NonceBitSize = 128;
    public static readonly int MacBitSize = 128;
    public static readonly int KeyBitSize = 256;

    private AesGcm256() { }

    public static byte[] NewKey()
    {
        var key = new byte[KeyBitSize / 8];
        Random.NextBytes(key);
        return key;
    }

    public static byte[] NewIv()
    {
        var iv = new byte[NonceBitSize / 8];
        Random.NextBytes(iv);
        return iv;
    }

    public static Byte[] HexToByte(string hexStr)
    {
        byte[] bArray = new byte[hexStr.Length / 2];
        for (int i = 0; i < (hexStr.Length / 2); i++)
        {
            byte firstNibble = Byte.Parse(hexStr.Substring((2 * i), 1), System.Globalization.NumberStyles.HexNumber); // [x,y)
            byte secondNibble = Byte.Parse(hexStr.Substring((2 * i) + 1, 1), System.Globalization.NumberStyles.HexNumber);
            int finalByte = (secondNibble) | (firstNibble << 4); // bit-operations only with numbers, not bytes.
            bArray[i] = (byte)finalByte;
        }
        return bArray;
    }


    public static string toHex(byte[] data)
    {
        string hex = string.Empty;
        foreach (byte c in data)
        {
            hex += c.ToString("X2");
        }
        return hex;
    }


    public static string toHex(string asciiString)
    {
        string hex = string.Empty;
        foreach (char c in asciiString)
        {
            int tmp = c;
            hex += string.Format("{0:x2}", System.Convert.ToUInt32(tmp.ToString()));
        }
        return hex;
    }

    public static string encrypt(string PlainText, byte[] key, byte[] iv)
    {
        string sR = string.Empty;
        try
        {
            byte[] plainBytes = Encoding.UTF8.GetBytes(PlainText);

            GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());
            AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);

            cipher.Init(true, parameters);

            byte[] encryptedBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
            Int32 retLen = cipher.ProcessBytes(plainBytes, 0, plainBytes.Length, encryptedBytes, 0);
            cipher.DoFinal(encryptedBytes, retLen);
            sR = Convert.ToBase64String(encryptedBytes, Base64FormattingOptions.None);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

        return sR;
    }


    public static string decrypt(string EncryptedText, byte[] key, byte[] iv)
    {
        string sR = string.Empty;
        try
        {
            byte[] encryptedBytes = Convert.FromBase64String(EncryptedText);

            GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());
            AeadParameters parameters = new AeadParameters(new KeyParameter(key), 128, iv, null);
            //ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key), iv);

            cipher.Init(false, parameters);
            byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];
            Int32 retLen = cipher.ProcessBytes(encryptedBytes, 0, encryptedBytes.Length, plainBytes, 0);
            cipher.DoFinal(plainBytes, retLen);

            sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }

        return sR;
    }

}
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 21 '23 at 01:22