douzhang5295
2014-06-05 23:48
浏览 310
已采纳

Golang AES ECB加密

Trying to emulate an algorithm in Go that is basically AES ECB Mode encryption.

Here's what I have so far

func Decrypt(data []byte) []byte {
    cipher, err := aes.NewCipher([]byte(KEY))
    if err == nil {
        cipher.Decrypt(data, PKCS5Pad(data))
        return data
    }
    return nil
}

I also have a PKCS5Padding algorithm, which is tested and working, which pads the data first. I cant find any information on how to switch the encryption mode in the Go AES package (it's definitely not in the docs).

I have this code in another language, which is how I know this algorithm isn't working quite correctly.

EDIT: Here is the method as I have interpreted from on the issue page

func AESECB(ciphertext []byte) []byte {
    cipher, _ := aes.NewCipher([]byte(KEY))
    fmt.Println("AESing the data")
    bs := 16
    if len(ciphertext)%bs != 0     {
        panic("Need a multiple of the blocksize")
    }

    plaintext := make([]byte, len(ciphertext))
    for len(plaintext) > 0 {
        cipher.Decrypt(plaintext, ciphertext)
        plaintext = plaintext[bs:]
        ciphertext = ciphertext[bs:]
    }
    return plaintext
}

This is actually not returning any data, maybe I screwed something up when changing it from encripting to decripting

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • doumanni3501 2017-01-14 16:59
    已采纳

    ESB is a very straightforward mode of operation. The data to be encrypted is divided into byte blocks, all having the same size. For each block, a cipher is applied, in this case AES, generating the encrypted block.

    The code snippet below decrypts AES-128 data in ECB (note that the block size is 16 bytes):

    package main
    
    import (
        "crypto/aes"
    )
    
    func DecryptAes128Ecb(data, key []byte) []byte {
        cipher, _ := aes.NewCipher([]byte(key))
        decrypted := make([]byte, len(data))
        size := 16
    
        for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
            cipher.Decrypt(decrypted[bs:be], data[bs:be])
        }
    
        return decrypted
    }
    

    As mentioned by @OneOfOne, ECB is insecure and very easy to detect, as repeated blocks will always encrypt to the same encrypted blocks. This Crypto SE answer gives a very good explanation why.

    打赏 评论
  • douqian2524 2014-06-05 23:58

    ECB is left out intentionally because it's insecure, check issue 5597.

    打赏 评论
  • dousong5161 2016-05-15 23:42

    I used your code so I feel the need to show you how I fixed it.

    I am doing the cryptopals challenges for this problem in Go.

    I'll walk you through the mistake since the code is mostly correct.

    for len(plaintext) > 0 {
        cipher.Decrypt(plaintext, ciphertext)
        plaintext = plaintext[bs:]
        ciphertext = ciphertext[bs:]
    }
    

    The loop does decrypt the data but does not put it anywhere. It simply shifts the two arrays along producing no output.

    i := 0
    plaintext := make([]byte, len(ciphertext))
    finalplaintext := make([]byte, len(ciphertext))
    for len(ciphertext) > 0 {
        cipher.Decrypt(plaintext, ciphertext)
        ciphertext = ciphertext[bs:]
        decryptedBlock := plaintext[:bs]
        for index, element := range decryptedBlock {
            finalplaintext[(i*bs)+index] = element
        }
        i++
        plaintext = plaintext[bs:]
    } 
    return finalplaintext[:len(finalplaintext)-5]
    

    What this new improvement does is store the decrypted data into a new []byte called finalplaintext. If you return that you get the data.

    It's important to do it this way since the Decrypt function only works one block size at a time.

    I return a slice because I suspect it's padded. I am new to cryptography and Go so anyone feel free to correct/revise this.

    打赏 评论
  • dongluxin2452 2017-11-01 11:16

    I was confused by a couple of things.

    First i needed a aes-256 version of the above algorithm, but apparently the aes.Blocksize (which is 16) won't change when the given key has length 32. So it is enough to give a key of length 32 to make the algorithm aes-256

    Second, the decrypted value still contains padding and the padding value changes depending on the length of the encrypted string. E.g. when there are 5 padding characters the padding character itself will be 5.

    Here is my function which returns a string:

    func DecryptAes256Ecb(hexString string, key string) string {
      data, _ := hex.DecodeString(hexString)
    
      cipher, _ := aes.NewCipher([]byte(key))
    
      decrypted := make([]byte, len(data))
      size := 16
    
      for bs, be := 0, size; bs < len(data); bs, be = bs+size, be+size {
        cipher.Decrypt(decrypted[bs:be], data[bs:be])
      }
    
      // remove the padding. The last character in the byte array is the number of padding chars
      paddingSize := int(decrypted[len(decrypted)-1])
      return string(decrypted[0 : len(decrypted)-paddingSize])
    }
    
    打赏 评论

相关推荐 更多相似问题