← Back to Writeups
CUSTOMMediumCrypto

Strange DES

XESXOR9/10/20262 min read
#crypto#custom#medium#des_weak_key_attack#involution_property

Strange DES

Platform: spbctf | Category: Crypto | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-03-09 | Status: Solved Techniques: des_weak_key_attack, involution_property

Summary

Task: DES encryption with hint about '1 in 2^54' probability. Solution: Exploit DES weak key involution property where E(E(m,k),k)=m to decrypt by encrypting again.

Strange DES — CryptoKids 2.0

Description

DES block cipher task with a hint about "1 in 2^54" probability.

Analysis

The hint "1 in 2^54" refers to the probability of randomly selecting a DES weak key. DES has exactly 4 weak keys out of 2^56 possible keys, giving probability 4/2^56 = 1/2^54.

DES Weak Keys:

  • 0x0000000000000000 (all zeros)
  • 0xFFFFFFFFFFFFFFFF (all ones)
  • 0xE0E0E0E0F1F1F1F1
  • 0x1F1F1F1F0E0E0E0E

Involution Property: With a weak key, DES encryption is its own inverse:

E(E(m, k), k) = m

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

This means encrypting the ciphertext again with the same weak key produces the plaintext!

Solution

  1. Identify that the hint points to DES weak keys
  2. Test each of the 4 weak keys against known plaintext-ciphertext pairs
  3. Once the correct weak key is found, "decrypt" by encrypting the ciphertext again
python
#!/usr/bin/env python3
from Crypto.Cipher import DES

# DES weak keys
WEAK_KEYS = [
    bytes.fromhex("0000000000000000"),
    bytes.fromhex("FFFFFFFFFFFFFFFF"),
    bytes.fromhex("E0E0E0E0F1F1F1F1"),
    bytes.fromhex("1F1F1F1F0E0E0E0E"),
]
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

def des_encrypt(data, key):
    """DES ECB encryption"""
    cipher = DES.new(key, DES.MODE_ECB)
    return cipher.encrypt(data)

# Known plaintext-ciphertext pair for verification
known_pt = b"????????"  # 8 bytes
known_ct = bytes.fromhex("...")

# Test each weak key
for key in WEAK_KEYS:
    if des_encrypt(known_pt, key) == known_ct:
        print(f"Found weak key: {key.hex()}")
        
        # Decrypt by encrypting again (involution property)
        ciphertext = bytes.fromhex("...")  # Target ciphertext
        plaintext = des_encrypt(ciphertext, key)
        print(f"Flag: {plaintext.decode()}")
        break
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Alternative: if key is 0xFFFFFFFFFFFFFFFF
key = bytes.fromhex("FFFFFFFFFFFFFFFF")
ciphertext = bytes.fromhex("...")
plaintext = des_encrypt(ciphertext, key)  # E(E(m,k),k) = m
print(plaintext)

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍