C Program to Encrypt and Decrypt a Password (XOR Cipher)

This classic exercise asks you to encrypt and decrypt a password in C. The right teaching tool for it is the XOR cipher: XOR each character with a key byte, and XOR-ing a second time with the same key restores the original — one function does both directions. This page gives you a tested implementation with the two traps handled that break most student versions (encrypted bytes that aren’t printable, and encrypted bytes that become '\0'), plus an honest section on why this is a learning exercise, not real security — the part interviewers actually want to hear.

How the XOR Cipher Works — Step by Step

  1. Pick a single-byte key, e.g. 0x5A.
  2. Encrypt: replace every character c with c ^ key.
  3. Decrypt: apply the exact same operation again — because (c ^ k) ^ k == c. XOR is its own inverse.
Character ASCII (hex) XOR 0x5A Result byte
S 0x53 0x53 ^ 0x5A 0x09
e 0x65 0x65 ^ 0x5A 0x3F
Z 0x5A 0x5A ^ 0x5A 0x00 — the trap!

Two consequences drive the whole design: encrypted bytes are often unprintable (so we print them as hex, not with %s), and a character equal to the key encrypts to 0x00 — a null byte in the middle of the “string”. Call strlen() on that and half your password silently disappears. The fix: measure the length once, before encrypting, and pass it around explicitly.

C Program to Encrypt and Decrypt a Password (XOR)

#include <stdio.h>
#include <string.h>

#define KEY 0x5A                 /* any non-zero byte works as the key */

static void xor_cipher(char *text, size_t len, char key)
{
    size_t i;

    for (i = 0; i < len; i++) {
        text[i] = (char)(text[i] ^ key);
    }
}

static void print_hex(const char *label, const char *text, size_t len)
{
    size_t i;

    printf("%s", label);
    for (i = 0; i < len; i++) {
        printf("%02X ", (unsigned char)text[i]);
    }
    printf("\n");
}

int main(void)
{
    char password[64];
    size_t len;

    printf("Enter the password: ");
    if (scanf("%63s", password) != 1) {
        printf("Invalid input.\n");
        return 1;
    }
    len = strlen(password);      /* remember the length BEFORE encrypting:
                                    an encrypted byte can become 0x00, which
                                    would silently truncate strlen() */

    printf("Original:        %s\n", password);
    xor_cipher(password, len, KEY);
    print_hex("Encrypted (hex): ", password, len);
    xor_cipher(password, len, KEY);      /* XOR twice = original */
    printf("Decrypted:       %s\n", password);
    return 0;
}

How to Compile and Run

gcc -ansi -Wall -Wextra -o xorcipher xorcipher.c
./xorcipher

Sample Input and Output

Test 1:

Enter the password: Secret123
Original:        Secret123
Encrypted (hex): 09 3F 39 28 3F 2E 6B 68 69
Decrypted:       Secret123

Test 2 — includes ‘Z’ (0x5A), the character equal to the key:

Enter the password: aZb
Original:        aZb
Encrypted (hex): 3B 00 38
Decrypted:       aZb

See the 00 in the middle? That’s ‘Z’ ^ 0x5A. Because the program carries len explicitly instead of re-calling strlen() on encrypted data, decryption still restores all three characters. A version that measures length after encrypting would return just a.

Code Explanation

  • xor_cipher() — one function encrypts and decrypts. That symmetry is the defining property of XOR: x ^ k ^ k == x for any values.
  • len = strlen(password) before the first cipher call — the load-bearing line, per the trap above.
  • print_hex() — encrypted bytes like 0x09 are control characters; printing them with %s produces garbage or invisible output. %02X on an unsigned char shows exactly what’s stored.
  • scanf("%63s", ...) — bounded read into the 64-byte buffer; unbounded %s is a buffer overflow.
  • The 2012 version of this post subtracted 0xFACA from each character — a value that doesn’t even fit in a byte, making the “encryption” undefined overflow behavior. XOR with a byte key is what the exercise should have been.

Why This Is NOT Real Security

Worth stating plainly, because interviewers ask: a single-byte XOR cipher is trivially breakable — there are only 255 possible keys to try, and frequency analysis cracks it instantly even without brute force. Real systems never encrypt-and-decrypt passwords at all: they store a salted, slow hash (bcrypt, scrypt, or Argon2) and compare hashes at login, so even a stolen database doesn’t reveal passwords. XOR’s legitimate uses are elsewhere: it’s a building block inside real ciphers (every round of AES XORs with round keys), and a classic tool in bit manipulation. Treat this program as XOR practice, not as a vault.

What This Program Teaches

  • XOR’s self-inverse property — the same function encrypts and decrypts
  • Binary data vs strings: why strlen() and %s stop being trustworthy after transformation
  • Printing bytes as hex with %02X and the unsigned char cast
  • What real password handling looks like (hashing, not encryption) — and why

Related C Programs

Test yourself: our free C Programming Quiz app for Android has 150+ questions with explanations for every answer.

Recommended Book

The C Programming Language by Kernighan & Ritchie remains the definitive C reference — we’ve solved all of its exercises. Also on Amazon.com.

5 comments on “C Program to Encrypt and Decrypt a Password (XOR Cipher)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>