DES decryption fails with "bad decrypt" or a padding error — what do I check?
Decryption requires every parameter to match the encrypting side: the key bytes, the key length (8/16/24), the mode (ECB/CBC), the IV, the padding, and whether the ciphertext is hex or Base64. The two most common traps: key length mismatch (a "DES key" of 32 hex characters is 16 bytes — that is 2-key 3DES, not single DES) and padding name confusion (Java's PKCS5Padding IS PKCS#7 for DES — don't pick None). The collapsible panel on the right shows an equivalent OpenSSL command for the current settings; sending it to the other side is the fastest way to find the divergence.
How long is a DES key? And 3DES?
Single DES: 64 bits nominal (8 bytes, 56 effective — one bit per byte is a parity bit). 3DES comes in two shapes: 2-key (16 bytes, K1‖K2 with K3=K1) and 3-key (24 bytes, K1‖K2‖K3). Their nominal key material is 112/168 bits, but the NIST security strength (SP 800-57 Part 1 Rev.5 Table 2) is about 80 and 112 bits respectively — and the 3-key shape is deprecated too. This tool identifies the shape from the byte count; anything that is not 8/16/24 throws — CryptoJS and openssl enc -K silently truncate or zero-pad instead, which is the number-one source of interop failures.
What is the IV and how long is it for DES?
The IV is the 8-byte value CBC mixes into the first block; ECB does not use one. It must be exactly 8 bytes (16 hex digits or 8 ASCII characters). Note that DES's IV is 8 bytes while AES's is 16 — copying an AES IV length over fails immediately. Never reuse an IV under the same key.
What does Java's DES/ECB/PKCS5Padding map to in this tool?
ECB mode + PKCS#7 padding. In the JCE, "PKCS5Padding" for DES executes the generic PKCS#7 algorithm — PKCS#5 only ever defined padding for 8-byte blocks, which happens to be DES's. Java Cipher.getInstance("DES/ECB/PKCS5Padding") output decrypts here with ECB + PKCS#7 and an 8-byte single-DES key. ⚠️ Java's 3DES (DESede) accepts only 24-byte keys — for the 2-key shape you must expand K1‖K2 to K1‖K2‖K1 yourself.
How do PHP's des-ede3 algorithm names map?
PHP borrows OpenSSL's names: des-ede3-cbc is 3-key 3DES + CBC, des-ede3-ecb is 3-key + ECB; des-ede-cbc is the 2-key shape. A 24-byte key selects 3-key, 16 bytes selects 2-key.
What are the parity bits in a DES key? Are they checked?
The low bit of each key byte is defined as a parity bit, so the true 56-bit key sits inside 64 bits. FIPS 46-3 does not require checking it — OpenSSL, Java and this tool all ignore it; any 8 bytes work, and changing parity bits does not change the ciphertext. .NET is the exception: it normalizes parity first and then checks a weak-key table, so zero and other weak keys are rejected by .NET while every other library encrypts happily — a trap that fires only when migrating test keys from Java/OpenSSL to .NET.
What happens in 3DES when K1 = K2?
In 2-key 3DES, K3 always equals K1; if K1 = K2 as well, the whole EDE chain collapses to single DES: E_K(D_K(E_K(P))) = E_K(P). The same happens when all three 8-byte components of a 24-byte key are identical. This tool still encrypts (interop first), but the real strength is then single-DES 56 bits, not 3DES.
Is DES still secure?
No — it is for legacy interop only. NIST withdrew single DES on 2005-05-19 (56-bit keys are brute-forceable; EFF's Deep Crack did it in 56 hours in 1998, 22 hours the next year with distributed.net). SP 800-131A Rev.2 lists 2-key TDEA encryption as Disallowed, and 3-key encryption as Disallowed after 2023-12-31 (decryption stays "Legacy use", kept only for reading historical data); SP 800-67 itself was withdrawn on 2024-01-01. The small 64-bit block also carries the Sweet32-class birthday bound (CVE-2016-2183) — NIST caps a single key bundle at 2²⁰ blocks (≈8 MB) of plaintext. Use AES-256 for anything new. This tool exists because banking clearings, payment gateways and old Java/.NET systems still run DES-era messages — fixing them starts with being able to read them.
Why does my 3DES result differ from Java/PHP?
Check in order of hit rate: ① key length — the other side's "32-hex DES key" is 16 bytes (2-key 3DES), you decrypted as single DES; ② mode — Java's bare "DES" defaults to ECB; OpenSSL's mode-less names des-ede3/des-ede are ECB (the CBC alias is -des3); PHP's openssl_encrypt requires an explicit algorithm name — the confusion there is that its default output is Base64 text, not raw bytes; ③ padding — old PHP mcrypt often used Zero padding, JCE uses PKCS#5/#7; ④ encoding — hex vs Base64, and case; ⑤ the CryptoJS password trap — passing a string as the "key" makes it run key derivation (MD5 + random salt, output prefixed Salted__, different every time), which is not the raw key at all — the top cause of "same code, different results every run". This tool lets you flip each one; the equivalent OpenSSL command on the right can be sent to the other side to reproduce.
ECB or CBC — which should I use?
Whatever the system you are talking to requires — legacy interop does not get a vote. If you do get to choose, always CBC with a random IV: ECB encrypts equal plaintext blocks to equal ciphertext blocks, and DES's small 8-byte blocks leak patterns even more visibly than AES-ECB. DES-era banking protocols use both; check the protocol document first.
Does this work offline? Is my data uploaded?
All computation happens in your browser (pure TypeScript, zero dependencies, zero network requests); keys and plaintext never leave the device. Once the page has loaded you can go offline and keep working. That is the only acceptable shape for a key-handling tool.
2-key or 3-key 3DES — which is more common in legacy systems?
2-key (16 bytes) is more common: banks and the payment industry deployed 16-byte-key hardware for compatibility, and SP 800-67 kept a separate (earlier) deprecation date for it. So a "3DES key" of 32 hex characters is most likely the 2-key shape. This tool detects the shape from the byte count automatically.