How to use crypto/rc4

Viewed 1269

I'm trying to encrypt/decrypt some data in Go with RC4. I found that Go provides rc4 algorithm in crypto/rc4 package. I tried to encrypt/decrypt data using the package but ciphertext and decrypted plaintext is not what I expected.

I compared with RC4 online tool something like this but I'm sure Go's rc4 package has some problem. Because after I encrypt plaintext with Go rc4 and decrypt ciphertext decrypted plaintext' is not what I encrypted. Should I find other library?

The code what I run is this.

package main

import (
    "crypto/rc4"
    "fmt"
    "log"
)

func main() {
    c, err := rc4.NewCipher([]byte("dsadsad"))
    if err != nil {
        log.Fatalln(err)
    }
    src := []byte("asdsad")
    dst := make([]byte, len(src))
    fmt.Println("Plaintext: ", src)
    c.XORKeyStream(dst, src)
    c.XORKeyStream(src, dst)
    fmt.Println("Ciphertext: ", dst)
    fmt.Println("Plaintext': ", src)
}

And the output is this

Plaintext:  [97 115 100 115 97 100]
Ciphertext:  [98 41 227 117 93 79]
Plaintext':  [111 154 128 112 250 88]
1 Answers

You can't use the same RC4 cipher to encrypt and then decrypt as it has internal state.

Construct a new cipher with the same key to decrypt:

// ENCRYPT
c, err := rc4.NewCipher([]byte("dsadsad"))
if err != nil {
    log.Fatalln(err)
}
src := []byte("asdsad")
fmt.Println("Plaintext: ", src)

dst := make([]byte, len(src))
c.XORKeyStream(dst, src)
fmt.Println("Ciphertext: ", dst)

// DECRYPT
c2, err := rc4.NewCipher([]byte("dsadsad"))
if err != nil {
    log.Fatalln(err)
}
src2 := make([]byte, len(dst))
c2.XORKeyStream(src2, dst)
fmt.Println("Plaintext': ", src2)

This will output (try it on the Go Playground):

Plaintext:  [97 115 100 115 97 100]
Ciphertext:  [98 41 227 117 93 79]
Plaintext':  [97 115 100 115 97 100]

But as the package doc states:

RC4 is cryptographically broken and should not be used for secure applications.

So use another, more secure algorithm such as crypto/aes.

Related