Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm looking to decrypt RC4 encrypted data. I've tried openssl but it doesn't support my key length of 64 bits (my version only has rc4 and rc4-40).

Encrypted data: 6dec8a6b6356b36e1f4c1a94c8f6dd5ddfd60108da479d5b4a8794afa468c7e78cd22946d7

Key: 24641684

The plain text should come out to: ThisIstheOriginaltext=theoriginaltext

Using this website http://rc4.online-domain-tools.com/ I am able to successfuly decrypt the data. However I am struggling to decrypt it in linux without the use of a website tool.

How can I decrypt this in linux?

share|improve this question
add comment

migrated from security.stackexchange.com Aug 15 '13 at 13:33

This question came from our site for Information security professionals.

2 Answers

It appears that the openssl utility that comes with most Linux distributions wasn't compiled with support for rc4-64.

What you can do is grab the latest source code from the OpenSSL website and compile it yourself.

share|improve this answer
    
Which version? openssl-1.0.1e only contains EVPs EVP_rc4() and EVP_rc4_40(), no mention of an explicit 64-bit variant except in the enc man page, which I suspect might be incorrect. –  mr.spuratic Aug 15 '13 at 10:37
add comment

The OpenSSL enc utility only supports rc4 which is implicitly 128-bit by default (EVP_rc4()), and rc4-40 (EVP_rc4_40()).

The former supports variable key sizes (via EVP_CIPHER_CTX_set_key_length()) but it seems enc does not support non-default key sizes, and never calls that set-length function. I'm not aware of any CLI tool or perl module which supports this.

Instead, you can trivially amend the do_crypt() RC2 80-bit example in the OpenSSL EVP_EncryptInit man page to do RC4-64 (or any other supported size):

// compile with: gcc -lcrypto -o rc4-64 rc4-64.c 
#include <stdio.h>
#include <openssl/ssl.h>

int main(int argc, char * argv[]) {
    FILE *in,*out; 

    // encrypt
    //in=fopen("rc4.in","r");
    //out=fopen("rc4.out","w");
    //do_crypt(in,out,1);
    //fclose(in); 
    //fclose(out);

    // decrypt
    in=fopen("rc4.out","r");
    out=fopen("rc4.txt","w");
    do_crypt(in,out,0);
    fclose(in); 
    fclose(out);
}

int do_crypt(FILE *in, FILE *out, int do_encrypt)
{
    /* Allow enough space in output buffer for additional block */
    unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
    int inlen, outlen;
    EVP_CIPHER_CTX ctx;

    /* Bogus key and IV: we'd normally set these from
       * another source.  */
    //unsigned char key[] = "0123456789";
    //unsigned char iv[] = "12345678";
    unsigned char key[] = "24641684";
    unsigned char iv[] = "\0\0\0\0\0\0\0\0";

    /* Don't set key or IV because we will modify the parameters */
    EVP_CIPHER_CTX_init(&ctx);

    /* set RC4 with 64-bit key */
    EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, do_encrypt);
    EVP_CIPHER_CTX_set_key_length(&ctx, 64/8)

    /* We finished modifying parameters so now we can set key and IV */

    EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
    for(;;) {
        inlen = fread(inbuf, 1, 1024, in);
        if(inlen <= 0) break;
        if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&ctx);
            return 0;
        }
        fwrite(outbuf, 1, outlen, out);
    }
    if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 0;
    }
    fwrite(outbuf, 1, outlen, out);
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

(Error checking etc omitted for brevity and clarity - this is not production code)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.