[{"data":1,"prerenderedAt":580},["ShallowReactive",2],{"navigation_docs":3,"-ciphers-aes-passphrase":228,"-ciphers-aes-passphrase-surround":575},[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-lucide-book-open",{"title":37,"path":38,"stem":39,"children":40,"icon":227},"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,179,183,187,191,195,199,203,207,211,215,219,223],{"title":42,"path":38,"stem":39},"Overview",{"title":44,"path":45,"stem":46},"Classical","\u002Fciphers\u002Fclassical","2.ciphers\u002F01.classical",{"title":48,"path":49,"stem":50},"Caesar","\u002Fciphers\u002Fcaesar","2.ciphers\u002F02.caesar",{"title":52,"path":53,"stem":54},"ROT-13","\u002Fciphers\u002Frot13","2.ciphers\u002F03.rot13",{"title":56,"path":57,"stem":58},"ROT-47","\u002Fciphers\u002Frot47","2.ciphers\u002F04.rot47",{"title":60,"path":61,"stem":62},"Atbash","\u002Fciphers\u002Fatbash","2.ciphers\u002F05.atbash",{"title":64,"path":65,"stem":66},"Affine","\u002Fciphers\u002Faffine","2.ciphers\u002F06.affine",{"title":68,"path":69,"stem":70},"Vigenère","\u002Fciphers\u002Fvigenere","2.ciphers\u002F07.vigenere",{"title":72,"path":73,"stem":74},"Beaufort","\u002Fciphers\u002Fbeaufort","2.ciphers\u002F08.beaufort",{"title":76,"path":77,"stem":78},"Autokey","\u002Fciphers\u002Fautokey","2.ciphers\u002F09.autokey",{"title":80,"path":81,"stem":82},"Trithemius","\u002Fciphers\u002Ftrithemius","2.ciphers\u002F10.trithemius",{"title":84,"path":85,"stem":86},"Alberti","\u002Fciphers\u002Falberti","2.ciphers\u002F11.alberti",{"title":88,"path":89,"stem":90},"Playfair","\u002Fciphers\u002Fplayfair","2.ciphers\u002F12.playfair",{"title":92,"path":93,"stem":94},"Polybius square","\u002Fciphers\u002Fpolybius","2.ciphers\u002F13.polybius",{"title":96,"path":97,"stem":98},"Morse code","\u002Fciphers\u002Fmorse","2.ciphers\u002F14.morse",{"title":100,"path":101,"stem":102},"Bacon's cipher","\u002Fciphers\u002Fbacon","2.ciphers\u002F15.bacon",{"title":104,"path":105,"stem":106},"Tap code","\u002Fciphers\u002Ftap-code","2.ciphers\u002F16.tap-code",{"title":108,"path":109,"stem":110},"ADFGVX","\u002Fciphers\u002Fadfgvx","2.ciphers\u002F17.adfgvx",{"title":112,"path":113,"stem":114},"Bifid","\u002Fciphers\u002Fbifid","2.ciphers\u002F18.bifid",{"title":116,"path":117,"stem":118},"Rail fence","\u002Fciphers\u002Frail-fence","2.ciphers\u002F19.rail-fence",{"title":120,"path":121,"stem":122},"Columnar transposition","\u002Fciphers\u002Fcolumnar","2.ciphers\u002F20.columnar",{"title":124,"path":125,"stem":126},"Enigma M3","\u002Fciphers\u002Fenigma","2.ciphers\u002F21.enigma",{"title":128,"path":129,"stem":130},"Block","\u002Fciphers\u002Fblock","2.ciphers\u002F22.block",{"title":132,"path":133,"stem":134},"AES (ECB)","\u002Fciphers\u002Faes","2.ciphers\u002F23.aes",{"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 (OFB)","\u002Fciphers\u002Faes-ofb","2.ciphers\u002F26.aes-ofb",{"title":148,"path":149,"stem":150},"AES (CTR)","\u002Fciphers\u002Faes-ctr","2.ciphers\u002F27.aes-ctr",{"title":152,"path":153,"stem":154},"AES (CCM)","\u002Fciphers\u002Faes-ccm","2.ciphers\u002F28.aes-ccm",{"title":156,"path":157,"stem":158},"AES (OCB)","\u002Fciphers\u002Faes-ocb","2.ciphers\u002F29.aes-ocb",{"title":160,"path":161,"stem":162},"AES (LRW)","\u002Fciphers\u002Faes-lrw","2.ciphers\u002F30.aes-lrw",{"title":164,"path":165,"stem":166},"AES (XTS)","\u002Fciphers\u002Faes-xts","2.ciphers\u002F31.aes-xts",{"title":168,"path":169,"stem":170},"AES (CBC-MAC)","\u002Fciphers\u002Faes-cbc-mac","2.ciphers\u002F32.aes-cbc-mac",{"title":172,"path":173,"stem":174},"AES (passphrase)","\u002Fciphers\u002Faes-passphrase","2.ciphers\u002F33.aes-passphrase",{"title":176,"path":177,"stem":178},"Rijndael (ECB)","\u002Fciphers\u002Frijndael","2.ciphers\u002F34.rijndael",{"title":180,"path":181,"stem":182},"DES (ECB)","\u002Fciphers\u002Fdes","2.ciphers\u002F35.des",{"title":184,"path":185,"stem":186},"DESX (ECB)","\u002Fciphers\u002Fdesx","2.ciphers\u002F36.desx",{"title":188,"path":189,"stem":190},"Triple DES (ECB)","\u002Fciphers\u002Ftriple-des","2.ciphers\u002F37.triple-des",{"title":192,"path":193,"stem":194},"Triple DES (CBC)","\u002Fciphers\u002Ftriple-des-cbc","2.ciphers\u002F38.triple-des-cbc",{"title":196,"path":197,"stem":198},"Blowfish (ECB)","\u002Fciphers\u002Fblowfish","2.ciphers\u002F39.blowfish",{"title":200,"path":201,"stem":202},"IDEA (ECB)","\u002Fciphers\u002Fidea","2.ciphers\u002F40.idea",{"title":204,"path":205,"stem":206},"Lucifer (ECB)","\u002Fciphers\u002Flucifer","2.ciphers\u002F41.lucifer",{"title":208,"path":209,"stem":210},"MARS (ECB)","\u002Fciphers\u002Fmars","2.ciphers\u002F42.mars",{"title":212,"path":213,"stem":214},"Serpent (ECB)","\u002Fciphers\u002Fserpent","2.ciphers\u002F43.serpent",{"title":216,"path":217,"stem":218},"Stream","\u002Fciphers\u002Fstream","2.ciphers\u002F44.stream",{"title":220,"path":221,"stem":222},"Rabbit","\u002Fciphers\u002Frabbit","2.ciphers\u002F45.rabbit",{"title":224,"path":225,"stem":226},"RC4","\u002Fciphers\u002Frc4","2.ciphers\u002F46.rc4","i-lucide-library",{"id":229,"title":172,"body":230,"description":568,"extension":569,"links":570,"meta":571,"navigation":572,"path":173,"seo":573,"stem":174,"__hash__":574},"docs\u002F2.ciphers\u002F33.aes-passphrase.md",{"type":231,"value":232,"toc":564},"minimark",[233,237,250,257,357,362,369,385,389,403,416,425,498,508,520,527,557,560],[234,235],"cipher-facts",{"name":236},"aes-passphrase",[238,239,240,241,245,246,249],"p",{},"Seen ",[242,243,244],"code",{},"var msg = \"U2FsdGVkX1...\""," in a page source? That's this one. ",[242,247,248],{},"CryptoJS.AES.encrypt(message, passphrase)"," writes it, and puzzle pages love it. Every other block cipher here wants a hex key. This one wants a password.",[238,251,252,253,256],{},"Decode the base64 and the first eight bytes read ",[242,254,255],{},"Salted__",". Then eight bytes of random salt, then the ciphertext. That's why every such string opens with the same ten characters. The salt is new on every run, so one message never looks the same twice.",[258,259,264],"pre",{"className":260,"code":261,"language":262,"meta":263,"style":263},"language-ts shiki shiki-themes ciphers ciphers ciphers","const aes = create(\"aes-passphrase\");\naes.decode(\"U2FsdGVkX18BI0VniavN73vYVeKsrRmd74V3dwhYQ3E=\", { key: \"secret\" }).text;\n\u002F\u002F \"ATTACK AT DAWN\"\naes.encode(\"ATTACK AT DAWN\", { key: \"secret\", salt: \"0123456789abcdef\" }).text;\n\u002F\u002F \"U2FsdGVkX18BI0VniavN73vYVeKsrRmd74V3dwhYQ3E=\"\n","ts","",[242,265,266,296,319,326,351],{"__ignoreMap":263},[267,268,271,275,279,282,286,289,293],"span",{"class":269,"line":270},"line",1,[267,272,274],{"class":273},"skH_V","const",[267,276,278],{"class":277},"s38Sx"," aes ",[267,280,281],{"class":273},"=",[267,283,285],{"class":284},"sK71F"," create",[267,287,288],{"class":277},"(",[267,290,292],{"class":291},"shU9J","\"aes-passphrase\"",[267,294,295],{"class":277},");\n",[267,297,299,302,305,307,310,313,316],{"class":269,"line":298},2,[267,300,301],{"class":277},"aes.",[267,303,304],{"class":284},"decode",[267,306,288],{"class":277},[267,308,309],{"class":291},"\"U2FsdGVkX18BI0VniavN73vYVeKsrRmd74V3dwhYQ3E=\"",[267,311,312],{"class":277},", { key: ",[267,314,315],{"class":291},"\"secret\"",[267,317,318],{"class":277}," }).text;\n",[267,320,322],{"class":269,"line":321},3,[267,323,325],{"class":324},"scIB-","\u002F\u002F \"ATTACK AT DAWN\"\n",[267,327,329,331,334,336,339,341,343,346,349],{"class":269,"line":328},4,[267,330,301],{"class":277},[267,332,333],{"class":284},"encode",[267,335,288],{"class":277},[267,337,338],{"class":291},"\"ATTACK AT DAWN\"",[267,340,312],{"class":277},[267,342,315],{"class":291},[267,344,345],{"class":277},", salt: ",[267,347,348],{"class":291},"\"0123456789abcdef\"",[267,350,318],{"class":277},[267,352,354],{"class":269,"line":353},5,[267,355,356],{"class":324},"\u002F\u002F \"U2FsdGVkX18BI0VniavN73vYVeKsrRmd74V3dwhYQ3E=\"\n",[358,359,361],"h2",{"id":360},"where-does-the-key-come-from","Where does the key come from?",[238,363,364,365,368],{},"From MD5, and not much of it. OpenSSL calls the recipe ",[242,366,367],{},"EVP_BytesToKey",", CryptoJS calls it EvpKDF. Hash the passphrase with the salt. Hash that result with the passphrase and the salt again. Repeat until there are bytes for the key and the 16-byte IV. For AES-256 that's three MD5 calls. Three. A GPU does billions of those a second, so a weak passphrase falls fast.",[238,370,371,372,376,377,380,381,384],{},"The body is plain ",[373,374,375],"a",{"href":137},"AES-CBC"," with PKCS#7 padding. It's the same bytes ",[242,378,379],{},"openssl enc -aes-256-cbc -md md5"," gives. OpenSSL switched its default digest to SHA-256 in 1.1.0, so leave out ",[242,382,383],{},"-md md5"," and you get something else.",[358,386,388],{"id":387},"the-options","The options",[238,390,391,394,395,398,399,402],{},[242,392,393],{},"key"," is the passphrase, any text, read as UTF-8. ",[242,396,397],{},"keyLength"," and ",[242,400,401],{},"iterations"," are the two knobs CryptoJS lets a page turn. Most pages leave them alone, so the defaults are 256 bits and one pass.",[238,404,405,407,408,411,412,415],{},[242,406,397],{}," is in bits, 128 to 1024 in steps of 32. CryptoJS counts 32-bit words, so ",[242,409,410],{},"CryptoJS.algo.AES.keySize = 32"," means ",[242,413,414],{},"keyLength: 1024",". Is that still AES? Not really. CryptoJS runs the Rijndael key schedule on whatever it gets and sets the rounds to words plus 6. A 1024-bit key gets 38 rounds. No standard has that. Some puzzle pages do, and so does this cipher.",[238,417,418,420,421,424],{},[242,419,401],{}," is ",[242,422,423],{},"EvpKDF.cfg.iterations",", 1 to 100000. Each extra pass hashes every derived block once more. The cap keeps one call under about a second.",[258,426,428],{"className":260,"code":427,"language":262,"meta":263,"style":263},"const wide = { key: \"secret\", keyLength: 1024, iterations: 10000 };\naes.encode(\"ATTACK AT DAWN\", { ...wide, salt: \"0123456789abcdef\" }).text;\n\u002F\u002F \"U2FsdGVkX18BI0VniavN7\u002FGNI6WzbZKfYzF61Y37l9k=\"\naes.decode(\"U2FsdGVkX18BI0VniavN7\u002FGNI6WzbZKfYzF61Y37l9k=\", { key: \"secret\" });\n\u002F\u002F CipherError: [aes-passphrase] Decrypted blocks do not end in PKCS#7 padding: wrong passphrase, keyLength or iterations\n",[242,429,430,447,470,475,493],{"__ignoreMap":263},[267,431,432,434,437,439,442,444],{"class":269,"line":270},[267,433,274],{"class":273},[267,435,436],{"class":277}," wide ",[267,438,281],{"class":273},[267,440,441],{"class":277}," { key: ",[267,443,315],{"class":291},[267,445,446],{"class":277},", keyLength: 1024, iterations: 10000 };\n",[267,448,449,451,453,455,457,460,463,466,468],{"class":269,"line":298},[267,450,301],{"class":277},[267,452,333],{"class":284},[267,454,288],{"class":277},[267,456,338],{"class":291},[267,458,459],{"class":277},", { ",[267,461,462],{"class":273},"...",[267,464,465],{"class":277},"wide, salt: ",[267,467,348],{"class":291},[267,469,318],{"class":277},[267,471,472],{"class":269,"line":321},[267,473,474],{"class":324},"\u002F\u002F \"U2FsdGVkX18BI0VniavN7\u002FGNI6WzbZKfYzF61Y37l9k=\"\n",[267,476,477,479,481,483,486,488,490],{"class":269,"line":328},[267,478,301],{"class":277},[267,480,304],{"class":284},[267,482,288],{"class":277},[267,484,485],{"class":291},"\"U2FsdGVkX18BI0VniavN7\u002FGNI6WzbZKfYzF61Y37l9k=\"",[267,487,312],{"class":277},[267,489,315],{"class":291},[267,491,492],{"class":277}," });\n",[267,494,495],{"class":269,"line":353},[267,496,497],{"class":324},"\u002F\u002F CipherError: [aes-passphrase] Decrypted blocks do not end in PKCS#7 padding: wrong passphrase, keyLength or iterations\n",[238,499,500,501,398,504,507],{},"Right passphrase, wrong knobs, and the padding check catches it. Pass ",[242,502,503],{},"wide",[242,505,506],{},"ATTACK AT DAWN"," comes back.",[238,509,510,513,514,516,517,519],{},[242,511,512],{},"salt"," matters only for ",[242,515,333],{},": 16 hex digits, random when you leave it out. ",[242,518,304],{}," reads the salt from the ciphertext and ignores the option.",[238,521,522,523,526],{},"The vectors come from crypto-js 4.2.0. The 128 and 256-bit ones match ",[242,524,525],{},"openssl enc -md md5"," too.",[238,528,529,530,532,533,536,537,539,540,542,543,546,547,549,550,552,553,556],{},"A missing ",[242,531,393],{}," is a ",[242,534,535],{},"MissingOptionError",". A ",[242,538,397],{}," or ",[242,541,401],{}," out of range is an ",[242,544,545],{},"InvalidOptionError",". On ",[242,548,304],{},", text that isn't base64, has no ",[242,551,255],{}," header, or isn't whole blocks after the salt is a ",[242,554,555],{},"CipherError",".",[238,558,559],{},"Plain TypeScript, not constant time. Good for opening a puzzle page, useless for locking anything.",[561,562,563],"style",{},"html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html pre.shiki code .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}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);}",{"title":263,"searchDepth":298,"depth":298,"links":565},[566,567],{"id":360,"depth":298,"text":361},{"id":387,"depth":298,"text":388},"What CryptoJS.AES.encrypt(message, passphrase) leaves on a page. Base64 starting U2FsdGVkX1, AES-CBC underneath, key and IV squeezed out of the passphrase with MD5.","md",null,{},true,{"title":172,"description":568},"Plmp9raJh8SNAJXyhcVYXPEE86YjUkNTthD22JyhZ48",[576,578],{"title":168,"path":169,"stem":170,"description":577,"children":-1},"CBC with a zero IV where only the last block survives, and that block is the tag. Nothing gets encrypted. UTF-8 text in, hex out, text bytes plus the tag.",{"title":176,"path":177,"stem":178,"description":579,"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.",1790843583857]