goencryptionrc4-cipher

How to use crypto/rc4


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]

Solution

  • 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.