Golang file encryption with crypto/aes lib

11,560

There is an example in the crypto/cipher package documentation.

I've tweaked the example to make new example for you:

func main() {
    // read content from your file
    plaintext, err := ioutil.ReadFile("you_file_to_be_encrypted")
    if err != nil {
        panic(err.Error())
    }

    // this is a key
    key := []byte("example key 1234")

    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err)
    }

    // The IV needs to be unique, but not secure. Therefore it's common to
    // include it at the beginning of the ciphertext.
    ciphertext := make([]byte, aes.BlockSize+len(plaintext))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        panic(err)
    }

    stream := cipher.NewCFBEncrypter(block, iv)
    stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

    // create a new file for saving the encrypted data.
    f, err := os.Create("a_aes.txt")
    if err != nil {
        panic(err.Error())
    }
    _, err = io.Copy(f, bytes.NewReader(ciphertext))
    if err != nil {
        panic(err.Error())
    }

    // done
}
Share:
11,560
W Khan
Author by

W Khan

Updated on June 25, 2022

Comments

  • W Khan
    W Khan almost 2 years

    I am trying to encrypt a file using the Go crypto/aes package. I have so far:

    func encrypt(source string, localdir string) error {
    
        src := filepath.Join("/home/bacula/cloud-backup/"+localdir, source)
        dst := filepath.Join(src + ".aes")
    
        fmt.Println(src)
        fmt.Println(dst)
        key := []byte("example key 1234")
    
        iv := []byte(key)[:aes.BlockSize]
    
        aesBlockEncrypter, err := aes.NewCipher([]byte(key))
        if err != nil {
                return err
        }
        aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, iv)
        aesEncrypter.XORKeyStream([]byte(dst), []byte(src))
        return nil
    }
    

    My first question is, how can I improve the way I am generating the IV? And secondly, there is no output file, so how do I stream the file through XORKeyStream?

    • elithrar
      elithrar over 8 years
      I strongly suggest using golang.org/x/crypto/nacl/secretbox if you need to encrypt files, as it also correctly authenticates the encrypted data.
    • Dave C
      Dave C over 8 years
      Do not roll your own encryption. Just using a secure primitive (AES) is not sufficient/secure if you don't use it correctly (IV, key, block mode, etc, etc). E.g. don't ever use a passphrase raw the way you do (there are key derivation functions such as is golang.org/x/crypto/pbkdf2 for that); use a cryptographically secure completely random IV, etc. Unless you're a cryptography expert you should be using a complete implementation written by an expert that handles all the details so you don't get it wrong.
    • Dave C
      Dave C over 8 years
      Also, crypto.stackexchange.com may be better for crypto questions such as "how do I generate an IV" or "how do I use a passphrase as an encryption key" (which are largely programming language agnostic questions).
    • W Khan
      W Khan over 8 years
      I did consider secretbox but there is very little documentation. I cant find any examples on there either. I wish there was better docs for it