How to decrypt data with AES in golang

1,696 views
Skip to first unread message

Hoping White

unread,
Jun 30, 2016, 2:57:11 AM6/30/16
to golang-nuts
Hi, all

I have a C# code to decrypt data as following

        public static string test(string input, string key)
        {
            if (((input == null) || string.IsNullOrEmpty(input.Trim())) || ((input == "false") || (input == "null")))
            {
                return string.Empty;
            }
            RijndaelManaged managed = new RijndaelManaged {
                KeySize = 0x100,
                BlockSize = 0x100,
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7,
                Key = Encoding.ASCII.GetBytes(key),
                IV = Encoding.ASCII.GetBytes(key)
            };
            try
            {
                byte[] buffer = Convert.FromBase64String(input);
                ICryptoTransform transform = managed.CreateDecryptor();
                byte[] bytes = null;
                using (MemoryStream stream = new MemoryStream())
                {
                    using (CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write))
                    {
                        stream2.Write(buffer, 0, buffer.Length);
                    }
                    bytes = stream.ToArray();
                }
                return Encoding.ASCII.GetString(bytes);
            }
            catch (Exception exception)
            {
                Console.Write (exception.ToString ());
                return string.Empty;
            }
        }
 

And I have write a golang code as following:

func test1(data, key string) {
raw, err := base64.StdEncoding.DecodeString(data)
if err != nil {
println(err.Error())
return
}

block, err := aes.NewCipher([]byte(key))
if err != nil {
println(err.Error())
return
}
mode := cipher.NewCBCDecrypter(block, []byte(key)[:aes.BlockSize])
mode.CryptBlocks(raw, raw)

println(string(raw))
}

Besides the PKCS7 padding problem, I can’t get the right answer. Can someone help me with this? Where do I get  this IV parameter?
I Can’t set IV as  C# does, because golang just complains about block size problem.  

Hoping White

unread,
Jun 30, 2016, 9:27:57 AM6/30/16
to Jason Woods, golang-nuts
Hi, Jason

Thanks for the reply. I find this project useful and it works for me like charm.


在 2016年6月30日,下午3:34,Jason Woods <de...@jasonwoods.me.uk> 写道:

Rijndael

awickert

unread,
Jun 30, 2016, 10:50:56 AM6/30/16
to golang-nuts
You geht the IV parameter e.g. from  the beginning of the ciphertext [suggested by go examples 0].  
But be careful the IV have to be unique to ensure a safe en- and decyrption. 

I also have modified your example a little bit so that it is working [1]. I have ignored the error checking, the checking of the block size and the encoding of the crypted data.  Nevertheless I hope it will help you. 


as....@gmail.com

unread,
Jul 2, 2016, 4:36:18 AM7/2/16
to golang-nuts
An IV is not a key, it just changes the state of the block chain and must the same size as the block. The key can be a different size than the block, the IV can not in this case. Your program complains because you are reusing the key as an IV, and this key-IV happens to be a different size than the block.

You shouldn't create the IV this way. The IV is supposed to be public, randomly generated, and shouldn't be reused.

If you don't want to use an IV, set it to a block of zeroes and then encrypt one random block of data before encrypting your plaintext. This randomizes the blockchain. When the decryptor receives the first ciphertext, he can decrypt the first block and then discard it. 

There is no need to base64 encode your data, it doesn't add anything in terms of secrecy.

Consider AES-GCM for authenticated encryption in your next project. 
Reply all
Reply to author
Forward
0 new messages