[{"data":1,"prerenderedAt":648},["ShallowReactive",2],{"navigation_docs":3,"-ciphers-triple-des-cbc":180,"-ciphers-triple-des-cbc-surround":643},[4,36],{"title":5,"path":6,"stem":7,"children":8,"icon":35},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Encode and decode","\u002Fguide\u002Ftransform","1.guide\u002F02.transform",{"title":16,"path":17,"stem":18},"Analysis","\u002Fguide\u002Fanalysis","1.guide\u002F03.analysis",{"title":20,"path":21,"stem":22},"CLI","\u002Fguide\u002Fcli","1.guide\u002F04.cli",{"title":24,"path":25,"stem":26},"Agents","\u002Fguide\u002Fagents","1.guide\u002F05.agents",{"title":28,"path":29,"stem":30},"Custom ciphers","\u002Fguide\u002Fcustom","1.guide\u002F06.custom",{"title":32,"path":33,"stem":34},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F07.playground","i-solar-book-2-linear",{"title":37,"path":38,"stem":39,"children":40,"icon":179},"Ciphers","\u002Fciphers","2.ciphers\u002F00.index",[41,43,47,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175],{"title":42,"path":38,"stem":39},"Overview",{"title":44,"path":45,"stem":46},"Caesar","\u002Fciphers\u002Fcaesar","2.ciphers\u002F01.caesar",{"title":48,"path":49,"stem":50},"ROT-13","\u002Fciphers\u002Frot13","2.ciphers\u002F02.rot13",{"title":52,"path":53,"stem":54},"ROT-47","\u002Fciphers\u002Frot47","2.ciphers\u002F03.rot47",{"title":56,"path":57,"stem":58},"Atbash","\u002Fciphers\u002Fatbash","2.ciphers\u002F04.atbash",{"title":60,"path":61,"stem":62},"Affine","\u002Fciphers\u002Faffine","2.ciphers\u002F05.affine",{"title":64,"path":65,"stem":66},"Vigenère","\u002Fciphers\u002Fvigenere","2.ciphers\u002F06.vigenere",{"title":68,"path":69,"stem":70},"Trithemius","\u002Fciphers\u002Ftrithemius","2.ciphers\u002F07.trithemius",{"title":72,"path":73,"stem":74},"Alberti","\u002Fciphers\u002Falberti","2.ciphers\u002F08.alberti",{"title":76,"path":77,"stem":78},"Playfair","\u002Fciphers\u002Fplayfair","2.ciphers\u002F09.playfair",{"title":80,"path":81,"stem":82},"Polybius square","\u002Fciphers\u002Fpolybius","2.ciphers\u002F10.polybius",{"title":84,"path":85,"stem":86},"Morse code","\u002Fciphers\u002Fmorse","2.ciphers\u002F11.morse",{"title":88,"path":89,"stem":90},"Bacon's cipher","\u002Fciphers\u002Fbacon","2.ciphers\u002F12.bacon",{"title":92,"path":93,"stem":94},"Tap code","\u002Fciphers\u002Ftap-code","2.ciphers\u002F13.tap-code",{"title":96,"path":97,"stem":98},"ADFGVX","\u002Fciphers\u002Fadfgvx","2.ciphers\u002F14.adfgvx",{"title":100,"path":101,"stem":102},"Bifid","\u002Fciphers\u002Fbifid","2.ciphers\u002F15.bifid",{"title":104,"path":105,"stem":106},"Rail fence","\u002Fciphers\u002Frail-fence","2.ciphers\u002F16.rail-fence",{"title":108,"path":109,"stem":110},"Columnar transposition","\u002Fciphers\u002Fcolumnar","2.ciphers\u002F17.columnar",{"title":112,"path":113,"stem":114},"Enigma M3","\u002Fciphers\u002Fenigma","2.ciphers\u002F18.enigma",{"title":116,"path":117,"stem":118},"Beaufort","\u002Fciphers\u002Fbeaufort","2.ciphers\u002F19.beaufort",{"title":120,"path":121,"stem":122},"Autokey","\u002Fciphers\u002Fautokey","2.ciphers\u002F20.autokey",{"title":124,"path":125,"stem":126},"AES (ECB)","\u002Fciphers\u002Faes","2.ciphers\u002F21.aes",{"title":128,"path":129,"stem":130},"Triple DES (ECB)","\u002Fciphers\u002Ftriple-des","2.ciphers\u002F22.triple-des",{"title":132,"path":133,"stem":134},"AES (LRW)","\u002Fciphers\u002Faes-lrw","2.ciphers\u002F23.aes-lrw",{"title":136,"path":137,"stem":138},"AES (CBC)","\u002Fciphers\u002Faes-cbc","2.ciphers\u002F24.aes-cbc",{"title":140,"path":141,"stem":142},"AES (CFB)","\u002Fciphers\u002Faes-cfb","2.ciphers\u002F25.aes-cfb",{"title":144,"path":145,"stem":146},"AES (CTR)","\u002Fciphers\u002Faes-ctr","2.ciphers\u002F26.aes-ctr",{"title":148,"path":149,"stem":150},"AES (CCM)","\u002Fciphers\u002Faes-ccm","2.ciphers\u002F27.aes-ccm",{"title":152,"path":153,"stem":154},"AES (OFB)","\u002Fciphers\u002Faes-ofb","2.ciphers\u002F28.aes-ofb",{"title":156,"path":157,"stem":158},"AES (OCB)","\u002Fciphers\u002Faes-ocb","2.ciphers\u002F29.aes-ocb",{"title":160,"path":161,"stem":162},"Triple DES (CBC)","\u002Fciphers\u002Ftriple-des-cbc","2.ciphers\u002F30.triple-des-cbc",{"title":164,"path":165,"stem":166},"Rijndael (ECB)","\u002Fciphers\u002Frijndael","2.ciphers\u002F31.rijndael",{"title":168,"path":169,"stem":170},"AES (XTS)","\u002Fciphers\u002Faes-xts","2.ciphers\u002F32.aes-xts",{"title":172,"path":173,"stem":174},"AES (CBC-MAC)","\u002Fciphers\u002Faes-cbc-mac","2.ciphers\u002F33.aes-cbc-mac",{"title":176,"path":177,"stem":178},"Blowfish (ECB)","\u002Fciphers\u002Fblowfish","2.ciphers\u002F34.blowfish","i-solar-library-linear",{"id":181,"title":160,"body":182,"description":636,"extension":637,"links":638,"meta":639,"navigation":640,"path":161,"seo":641,"stem":162,"__hash__":642},"docs\u002F2.ciphers\u002F30.triple-des-cbc.md",{"type":183,"value":184,"toc":632},"minimark",[185,189,211,222,388,399,457,460,465,476,527,530,534,541,591,602,605,625,628],[186,187],"cipher-facts",{"name":188},"triple-des-cbc",[190,191,192,193,197,198,201,202,206,207,210],"p",{},"This is the Triple DES you actually run into. Old PKCS#12 files, the ",[194,195,196],"code",{},"3DES_EDE_CBC"," suites in TLS and ",[194,199,200],{},"3des-cbc"," in SSH all use it in CBC, not ECB. The block function is the same as in ",[203,204,205],"a",{"href":129},"Triple DES",", DES encrypt, decrypt, encrypt under K1, K2 and K3. The chaining is the same as in ",[203,208,209],{"href":137},"AES-CBC",", from NIST SP 800-38A. Each plaintext block is XORed with the ciphertext block before it, the first one with the IV, and then encrypted.",[190,212,213,214,217,218,221],{},"The key is 32 or 48 hex digits, as in ECB, and parity bits still don't matter. ",[194,215,216],{},"iv"," is required and it's 16 hex digits, not 32. A Triple DES block is 8 bytes, so an IV copied over from AES is an ",[194,219,220],{},"InvalidOptionError",", not a silent cut. Text goes in as UTF-8 with PKCS#7 padding, ciphertext comes out as lowercase hex.",[223,224,229],"pre",{"className":225,"code":226,"language":227,"meta":228,"style":228},"language-ts shiki shiki-themes github-light github-light poimandres","const cbc = create(\"triple-des-cbc\");\nconst key = \"0123456789abcdef23456789abcdef01456789abcdef0123\";\nconst iv = \"0001020304050607\";\ncbc.encode(\"ATTACK AT DAWN\", { key, iv }).text; \u002F\u002F \"00b5ad5bd633b1c564e7e3a858c7d8fb\"\ncbc.decode(\"00b5ad5bd633b1c564e7e3a858c7d8fb\", { key, iv }).text; \u002F\u002F \"ATTACK AT DAWN\"\n","ts","",[194,230,231,267,288,307,352],{"__ignoreMap":228},[232,233,236,240,244,247,251,255,259,262,264],"span",{"class":234,"line":235},"line",1,[232,237,239],{"class":238},"s1TYA","const",[232,241,243],{"class":242},"saoiD"," cbc",[232,245,246],{"class":238}," =",[232,248,250],{"class":249},"sULi6"," create",[232,252,254],{"class":253},"sKlNE","(",[232,256,258],{"class":257},"scVjq","\"",[232,260,188],{"class":261},"sQ7BG",[232,263,258],{"class":257},[232,265,266],{"class":253},");\n",[232,268,270,272,275,277,280,283,285],{"class":234,"line":269},2,[232,271,239],{"class":238},[232,273,274],{"class":242}," key",[232,276,246],{"class":238},[232,278,279],{"class":257}," \"",[232,281,282],{"class":261},"0123456789abcdef23456789abcdef01456789abcdef0123",[232,284,258],{"class":257},[232,286,287],{"class":253},";\n",[232,289,291,293,296,298,300,303,305],{"class":234,"line":290},3,[232,292,239],{"class":238},[232,294,295],{"class":242}," iv",[232,297,246],{"class":238},[232,299,279],{"class":257},[232,301,302],{"class":261},"0001020304050607",[232,304,258],{"class":257},[232,306,287],{"class":253},[232,308,310,314,317,320,322,324,327,329,332,334,337,339,342,345,348],{"class":234,"line":309},4,[232,311,313],{"class":312},"spVlQ","cbc",[232,315,316],{"class":253},".",[232,318,319],{"class":249},"encode",[232,321,254],{"class":253},[232,323,258],{"class":257},[232,325,326],{"class":261},"ATTACK AT DAWN",[232,328,258],{"class":257},[232,330,331],{"class":253},", {",[232,333,274],{"class":312},[232,335,336],{"class":253},",",[232,338,295],{"class":312},[232,340,341],{"class":253}," }).",[232,343,344],{"class":312},"text",[232,346,347],{"class":253},"; ",[232,349,351],{"class":350},"sjhu3","\u002F\u002F \"00b5ad5bd633b1c564e7e3a858c7d8fb\"\n",[232,353,355,357,359,362,364,366,369,371,373,375,377,379,381,383,385],{"class":234,"line":354},5,[232,356,313],{"class":312},[232,358,316],{"class":253},[232,360,361],{"class":249},"decode",[232,363,254],{"class":253},[232,365,258],{"class":257},[232,367,368],{"class":261},"00b5ad5bd633b1c564e7e3a858c7d8fb",[232,370,258],{"class":257},[232,372,331],{"class":253},[232,374,274],{"class":312},[232,376,336],{"class":253},[232,378,295],{"class":312},[232,380,341],{"class":253},[232,382,344],{"class":312},[232,384,347],{"class":253},[232,386,387],{"class":350},"\u002F\u002F \"ATTACK AT DAWN\"\n",[190,389,390,391,394,395,398],{},"OpenSSL agrees. ",[194,392,393],{},"-des-ede3-cbc"," takes the 48-digit key, ",[194,396,397],{},"-des-ede-cbc"," the 32-digit one:",[223,400,404],{"className":401,"code":402,"language":403,"meta":228,"style":228},"language-bash shiki shiki-themes github-light github-light poimandres","printf %s \"ATTACK AT DAWN\" | openssl enc -des-ede3-cbc -K 0123456789abcdef23456789abcdef01456789abcdef0123 -iv 0001020304050607 | xxd -p\n","bash",[194,405,406],{"__ignoreMap":228},[232,407,408,412,416,418,420,422,425,429,432,436,439,442,445,449,451,454],{"class":234,"line":235},[232,409,411],{"class":410},"s39Ir","printf",[232,413,415],{"class":414},"sX7Zv"," %s",[232,417,279],{"class":257},[232,419,326],{"class":261},[232,421,258],{"class":257},[232,423,424],{"class":238}," |",[232,426,428],{"class":427},"sseY5"," openssl",[232,430,431],{"class":414}," enc",[232,433,435],{"class":434},"sqT1Y"," -des-ede3-cbc",[232,437,438],{"class":434}," -K",[232,440,441],{"class":414}," 0123456789abcdef23456789abcdef01456789abcdef0123",[232,443,444],{"class":434}," -iv",[232,446,448],{"class":447},"siHFe"," 0001020304050607",[232,450,424],{"class":238},[232,452,453],{"class":427}," xxd",[232,455,456],{"class":434}," -p\n",[190,458,459],{},"The tests check the mode against the multi-block CBC vectors from NIST's CAVP, two-key and three-key.",[461,462,464],"h2",{"id":463},"what-the-chain-fixes","What the chain fixes",[190,466,467,468,471,472,475],{},"Sixteen ",[194,469,470],{},"A","s, two equal blocks. ECB gives two equal blocks back, ",[194,473,474],{},"9f6ca443ceebf424"," twice. CBC doesn't:",[223,477,479],{"className":225,"code":478,"language":227,"meta":228,"style":228},"cbc.encode(\"A\".repeat(16), { key, iv }).text;\n\u002F\u002F c93fea87be35b90e 9429d1e9334f7bc4 5917c5548017b5ab\n",[194,480,481,522],{"__ignoreMap":228},[232,482,483,485,487,489,491,493,495,497,499,502,504,507,510,512,514,516,518,520],{"class":234,"line":235},[232,484,313],{"class":312},[232,486,316],{"class":253},[232,488,319],{"class":249},[232,490,254],{"class":253},[232,492,258],{"class":257},[232,494,470],{"class":261},[232,496,258],{"class":257},[232,498,316],{"class":253},[232,500,501],{"class":249},"repeat",[232,503,254],{"class":253},[232,505,506],{"class":447},"16",[232,508,509],{"class":253},"), {",[232,511,274],{"class":312},[232,513,336],{"class":253},[232,515,295],{"class":312},[232,517,341],{"class":253},[232,519,344],{"class":312},[232,521,287],{"class":253},[232,523,524],{"class":234,"line":269},[232,525,526],{"class":350},"\u002F\u002F c93fea87be35b90e 9429d1e9334f7bc4 5917c5548017b5ab\n",[190,528,529],{},"Spaces added to show the blocks, and the last one is padding. Nothing repeats, because the second block was mixed with the first one's ciphertext before DES saw it. Same message, same key and same IV still give the same ciphertext, though. So a new IV for every message.",[461,531,533],{"id":532},"what-it-doesnt-fix","What it doesn't fix",[190,535,536,537,540],{},"On decryption the IV gets XORed in after Triple DES. Change the IV and you change the first block of plaintext, bit for bit, no key needed. With 8-byte blocks the first block is ",[194,538,539],{},"ATTACK A",":",[223,542,544],{"className":225,"code":543,"language":227,"meta":228,"style":228},"cbc.decode(\"00b5ad5bd633b1c564e7e3a858c7d8fb\", { key, iv: \"05101007090a0607\" }).text;\n\u002F\u002F \"DEFEND AT DAWN\"\n",[194,545,546,586],{"__ignoreMap":228},[232,547,548,550,552,554,556,558,560,562,564,566,568,571,573,575,578,580,582,584],{"class":234,"line":235},[232,549,313],{"class":312},[232,551,316],{"class":253},[232,553,361],{"class":249},[232,555,254],{"class":253},[232,557,258],{"class":257},[232,559,368],{"class":261},[232,561,258],{"class":257},[232,563,331],{"class":253},[232,565,274],{"class":312},[232,567,336],{"class":253},[232,569,295],{"class":570},"snHMy",[232,572,540],{"class":253},[232,574,279],{"class":257},[232,576,577],{"class":261},"05101007090a0607",[232,579,258],{"class":257},[232,581,341],{"class":253},[232,583,344],{"class":312},[232,585,287],{"class":253},[232,587,588],{"class":234,"line":269},[232,589,590],{"class":350},"\u002F\u002F \"DEFEND AT DAWN\"\n",[190,592,593,594,597,598,601],{},"That IV is the old one XORed with ",[194,595,596],{},"ATTACK"," and ",[194,599,600],{},"DEFEND"," at bytes 0 to 5. Same bit flipping as in AES-CBC, and the same padding oracle if an error gives away bad padding.",[190,603,604],{},"The small block causes one more problem. 64 bits means ciphertext blocks start repeating after around 2^32 blocks, about 32 GB under one key. In CBC, two equal ciphertext blocks give away the XOR of two plaintext blocks. That's Sweet32 from 2016, and a big part of why NIST disallowed Triple DES for encryption after 2023. Nobody's pushing 32 GB through this implementation, it's far too slow for that.",[190,606,607,608,610,611,613,614,617,618,620,621,624],{},"A key that isn't 32 or 48 hex digits is an ",[194,609,220],{},", and so is an ",[194,612,216],{}," that isn't 16. A missing key or IV is a ",[194,615,616],{},"MissingOptionError",". On ",[194,619,361],{},", hex that isn't whole 8-byte blocks is a ",[194,622,623],{},"CipherError",". So is a wrong key, since the padding almost never survives it, and so are decrypted bytes that aren't UTF-8. A wrong IV garbles only the first block, and those bytes are almost never UTF-8. But an IV that's only a little off, like the one above, decodes without a word.",[190,626,627],{},"No integrity check, plain TypeScript over bit arrays, not constant time. For puzzles and legacy files. Don't protect anything real with it.",[629,630,631],"style",{},"html pre.shiki code .s1TYA, html code.shiki .s1TYA{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#91B4D5}html pre.shiki code .saoiD, html code.shiki .saoiD{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#E4F0FB}html pre.shiki code .sULi6, html code.shiki .sULi6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#E4F0FBD0}html pre.shiki code .sKlNE, html code.shiki .sKlNE{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#A6ACCD}html pre.shiki code .scVjq, html code.shiki .scVjq{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#A6ACCD}html pre.shiki code .sQ7BG, html code.shiki .sQ7BG{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#5DE4C7}html pre.shiki code .spVlQ, html code.shiki .spVlQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E4F0FB}html pre.shiki code .sjhu3, html code.shiki .sjhu3{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#767C9DB0;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s39Ir, html code.shiki .s39Ir{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#91B4D5}html pre.shiki code .sX7Zv, html code.shiki .sX7Zv{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#ADD7FF}html pre.shiki code .sseY5, html code.shiki .sseY5{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#91B4D5}html pre.shiki code .sqT1Y, html code.shiki .sqT1Y{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#ADD7FF}html pre.shiki code .siHFe, html code.shiki .siHFe{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#5DE4C7}html pre.shiki code .snHMy, html code.shiki .snHMy{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#ADD7FF}",{"title":228,"searchDepth":269,"depth":269,"links":633},[634,635],{"id":463,"depth":269,"text":464},{"id":532,"depth":269,"text":533},"Triple DES with the blocks chained. Every 8-byte block is mixed with the ciphertext before it, so equal blocks stop looking equal. UTF-8 text in, hex out.","md",null,{},true,{"title":160,"description":636},"T-RJXi-GaogPPXUgqZimjbXCBhrkyIApb21Sq42fOTI",[644,646],{"title":156,"path":157,"stem":158,"description":645,"children":-1},"AES in OCB mode, RFC 7253. One AES call per block encrypts and authenticates at once, and decoding refuses anything that was changed. UTF-8 text in, hex out, text bytes plus the tag.",{"title":164,"path":165,"stem":166,"description":647,"children":-1},"The cipher AES was cut from, with the wider blocks it lost on the way. Block and key each 128 to 256 bits, UTF-8 text in, hex out.",1790291185306]