How to encrypt and decrypt text with RC4

This page encrypts and decrypts text with RC4 inside the browser. The result is Base64 text in the CryptoJS passphrase container that begins with U2FsdGVkX1, and the same passphrase turns it back into the original sentence. RC4 is a legacy stream cipher with known biases, so use the page to read old data and to reproduce other tools' output, not to protect anything new.

The text and the passphrase stay in the page: nothing is uploaded, and a run finishes with the network switched off. Nothing is stored either, so a lost passphrase cannot be recovered here. Input and output are text only — there is no file upload, no binary mode and no download button.

  1. Paste the text to encrypt into the text area and type the passphrase into the key field.
  2. Press Encrypt. The Base64 result appears in the panel below; the same text and passphrase produce a different string every time, because each run draws a new random salt.
  3. To read a message back, paste the whole Base64 string into the text area, enter the same passphrase and press Decrypt.
  4. Copy puts the result on the clipboard; Clear empties the text area, the passphrase and the result.
  5. Keep the passphrase somewhere safe. It is the only secret in the process, and the page keeps no copy of it or of the text.

The container, OpenSSL and the limits of RC4

What the Base64 result is made of

The output is a CryptoJS passphrase container: the eight bytes Salted__ (which is why the string starts with U2FsdGVkX1), eight random salt bytes, and then the RC4 output, all Base64 encoded. Key material is derived from the passphrase and the salt with EVP_BytesToKey and MD5 and is 32 bytes long. In testing, an independent implementation of that derivation ran RC4 on this page's output and recovered the text, and ciphertext built the same way decrypted back in the page.

Decryption takes the salt from the container, so only the passphrase has to travel with the ciphertext. A different salt means a different keystream, which is why one sentence encrypts differently on every run and why all of those strings still decode to the same text. The plaintext is read as UTF-8; anything that is not valid UTF-8 cannot be represented here.

OpenSSL and this page do not speak the same RC4

OpenSSL derives a 16-byte RC4 key (openssl enc -rc4 -md md5; -rc4-40 uses five bytes), while CryptoJS on this page uses 32 bytes, so the two cannot read each other's output. In testing, OpenSSL turned a page ciphertext into garbage, and this page answered an openssl enc -rc4 container with the wrong-passphrase message. Handing OpenSSL a longer key does not fix it: -K with 64 hex characters printed “hex string is too long, ignoring excess” and used the first 16 bytes.

Interoperating therefore means implementing the same key derivation: EVP_BytesToKey(MD5) over the passphrase and the salt, take 32 bytes, then run RC4. If you want a command-line counterpart that works unmodified, the AES page in this family matches openssl enc -aes-256-cbc -md md5 exactly, and openssl enc -rc4 is legacy itself — OpenSSL 3 only offers it through the legacy provider.

Wrong passphrase, edited bytes, truncated ciphertext

A wrong passphrase or a string that is not one of these containers is reported under the buttons in the language of the page. The check is a UTF-8 validity test on the decrypted bytes, so it is a convenience rather than a guarantee: in testing, 24 wrong-passphrase attempts were all flagged, but a keystream that happens to decode as text passes silently.

RC4 provides no authentication, and neither edits nor truncation are caught reliably. Flipping one byte of the ciphertext changed exactly one character of the recovered plaintext and showed no warning, and cutting the ciphertext to about 60 % of its length returned the first part of the sentence as if it were the whole message. Where tampering matters, use an authenticated cipher such as AES-GCM; this page is for reproducing and inspecting legacy RC4 data.

Recent tools: