[{"data":1,"prerenderedAt":1851},["ShallowReactive",2],{"navigation":3,"-jwt-jwe-encrypting":167,"-jwt-jwe-encrypting-surround":1848},[4,22,78,106,141,148],{"title":5,"path":6,"stem":7,"children":8},"Introduction","\u002Fgetting-started","0.Getting-Started\u002F0.index",[9,10,14,18],{"title":5,"path":6,"stem":7},{"title":11,"path":12,"stem":13},"Installation","\u002Fgetting-started\u002Finstallation","0.Getting-Started\u002F1.installation",{"title":15,"path":16,"stem":17},"Quickstart","\u002Fgetting-started\u002Fquickstart","0.Getting-Started\u002F2.quickstart",{"title":19,"path":20,"stem":21},"Core concepts","\u002Fgetting-started\u002Fcore-concepts","0.Getting-Started\u002F3.core-concepts",{"title":23,"path":24,"stem":25,"children":26,"icon":28},"JWT","\u002Fjwt","1.JWT\u002F0.index",[27,29,52],{"title":23,"path":24,"stem":25,"icon":28},"i-carbon-certificate",{"title":30,"path":31,"stem":32,"children":33,"icon":35},"JWS","\u002Fjwt\u002Fjws","1.JWT\u002F1.JWS\u002F0.index",[34,36,40,44,48],{"title":30,"path":31,"stem":32,"icon":35},"i-carbon-document-signed",{"title":37,"path":38,"stem":39},"Signing","\u002Fjwt\u002Fjws\u002Fsigning","1.JWT\u002F1.JWS\u002F1.signing",{"title":41,"path":42,"stem":43},"Verifying","\u002Fjwt\u002Fjws\u002Fverifying","1.JWT\u002F1.JWS\u002F2.verifying",{"title":45,"path":46,"stem":47},"Multi-signature","\u002Fjwt\u002Fjws\u002Fmulti-signature","1.JWT\u002F1.JWS\u002F3.multi-signature",{"title":49,"path":50,"stem":51},"Algorithms","\u002Fjwt\u002Fjws\u002Falgorithms","1.JWT\u002F1.JWS\u002F4.algorithms",{"title":53,"path":54,"stem":55,"children":56,"icon":58},"JWE","\u002Fjwt\u002Fjwe","1.JWT\u002F2.JWE\u002F0.index",[57,59,63,67,71,75],{"title":53,"path":54,"stem":55,"icon":58},"i-carbon-locked",{"title":60,"path":61,"stem":62},"Encrypting","\u002Fjwt\u002Fjwe\u002Fencrypting","1.JWT\u002F2.JWE\u002F1.encrypting",{"title":64,"path":65,"stem":66},"Decrypting","\u002Fjwt\u002Fjwe\u002Fdecrypting","1.JWT\u002F2.JWE\u002F2.decrypting",{"title":68,"path":69,"stem":70},"Multi-recipient","\u002Fjwt\u002Fjwe\u002Fmulti-recipient","1.JWT\u002F2.JWE\u002F3.multi-recipient",{"title":72,"path":73,"stem":74},"ECDH-ES and end-to-end encryption","\u002Fjwt\u002Fjwe\u002Fecdh-es","1.JWT\u002F2.JWE\u002F4.ecdh-es",{"title":49,"path":76,"stem":77},"\u002Fjwt\u002Fjwe\u002Falgorithms","1.JWT\u002F2.JWE\u002F5.algorithms",{"title":79,"path":80,"stem":81,"children":82,"icon":84},"Examples","\u002Fexamples","10.Examples\u002F0.index",[83,85,90,94,98,102],{"title":79,"path":80,"stem":81,"icon":84},"i-carbon-code-reference",{"title":86,"path":87,"stem":88,"icon":89},"Authentication basics","\u002Fexamples\u002Fauthentication-basics","10.Examples\u002F1.authentication-basics","i-lucide-code",{"title":91,"path":92,"stem":93,"icon":89},"Consuming a JWKS endpoint","\u002Fexamples\u002Fjwks-endpoint","10.Examples\u002F2.jwks-endpoint",{"title":95,"path":96,"stem":97,"icon":89},"Refresh token pattern","\u002Fexamples\u002Frefresh-token-pattern","10.Examples\u002F3.refresh-token-pattern",{"title":99,"path":100,"stem":101,"icon":89},"End-to-end encryption","\u002Fexamples\u002Fend-to-end-encryption","10.Examples\u002F4.end-to-end-encryption",{"title":103,"path":104,"stem":105,"icon":89},"Signed receipts","\u002Fexamples\u002Fsigned-receipts","10.Examples\u002F5.signed-receipts",{"title":107,"path":108,"stem":109,"children":110,"icon":112},"JWK","\u002Fjwk","2.JWK\u002F0.index",[111,113,117,121,125,129,133,137],{"title":107,"path":108,"stem":109,"icon":112},"i-carbon-two-factor-authentication",{"title":114,"path":115,"stem":116},"Generating keys","\u002Fjwk\u002Fgenerating","2.JWK\u002F1.generating",{"title":118,"path":119,"stem":120},"Importing and exporting","\u002Fjwk\u002Fimport-export","2.JWK\u002F2.import-export",{"title":122,"path":123,"stem":124},"PEM conversion","\u002Fjwk\u002Fpem","2.JWK\u002F3.pem",{"title":126,"path":127,"stem":128},"Key wrapping","\u002Fjwk\u002Fwrapping","2.JWK\u002F4.wrapping",{"title":130,"path":131,"stem":132},"Password derivation","\u002Fjwk\u002Fpassword-derivation","2.JWK\u002F5.password-derivation",{"title":134,"path":135,"stem":136},"JWK Sets","\u002Fjwk\u002Fjwk-sets","2.JWK\u002F6.jwk-sets",{"title":138,"path":139,"stem":140},"JWK cache","\u002Fjwk\u002Fcache","2.JWK\u002F7.cache",{"title":142,"path":143,"stem":144,"children":145,"icon":147},"Utilities","\u002Futilities","3.Utilities\u002F0.index",[146],{"title":142,"path":143,"stem":144,"icon":147},"i-carbon-tool-box",{"title":149,"path":150,"stem":151,"children":152,"icon":154},"Adapters","\u002Fadapters","99.Adapters\u002F0.index",[153,155,159,163],{"title":149,"path":150,"stem":151,"icon":154},"i-carbon-plug",{"title":156,"path":157,"stem":158},"H3 sessions","\u002Fadapters\u002Fh3-sessions","99.Adapters\u002F1.h3-sessions",{"title":160,"path":161,"stem":162},"Lifecycle hooks","\u002Fadapters\u002Fhooks","99.Adapters\u002F2.hooks",{"title":164,"path":165,"stem":166},"Lower-level functions","\u002Fadapters\u002Flower-level","99.Adapters\u002F3.lower-level",{"id":168,"title":60,"body":169,"description":178,"extension":1843,"meta":1844,"navigation":1845,"path":61,"seo":1846,"stem":62,"__hash__":1847},"content\u002F1.JWT\u002F2.JWE\u002F1.encrypting.md",{"type":170,"value":171,"toc":1824},"minimark",[172,202,215,220,307,340,347,351,367,463,471,475,480,483,529,540,558,562,569,622,626,629,692,699,713,795,809,870,878,885,888,913,940,944,947,1023,1030,1074,1078,1081,1162,1171,1175,1181,1242,1255,1259,1269,1371,1386,1392,1395,1786,1790,1820],[173,174,179],"pre",{"className":175,"code":176,"language":177,"meta":178,"style":178},"language-ts shiki shiki-themes github-light github-dark github-dark","encrypt(payload, key, options?)\n","ts","",[180,181,182],"code",{"__ignoreMap":178},[183,184,187,191,195,199],"span",{"class":185,"line":186},"line",1,[183,188,190],{"class":189},"shcOC","encrypt",[183,192,194],{"class":193},"slsVL","(payload, key, options",[183,196,198],{"class":197},"so5gQ","?",[183,200,201],{"class":193},")\n",[203,204,205,206,210,211,214],"p",{},"Produces a ",[207,208,209],"strong",{},"compact JWE"," — five base64url segments: ",[180,212,213],{},"\u003Cheader>.\u003CencryptedKey>.\u003Civ>.\u003Cciphertext>.\u003Ctag>",".",[216,217,219],"h2",{"id":218},"parameters","Parameters",[221,222,223,236],"table",{},[224,225,226],"thead",{},[227,228,229,233],"tr",{},[230,231,232],"th",{},"Name",[230,234,235],{},"Type",[237,238,239,252,264,277,293],"tbody",{},[227,240,241,247],{},[242,243,244],"td",{},[180,245,246],{},"payload",[242,248,249],{},[180,250,251],{},"string | Uint8Array | Record\u003Cstring, unknown>",[227,253,254,259],{},[242,255,256],{},[180,257,258],{},"key",[242,260,261],{},[180,262,263],{},"string | JWEEncryptJWK | CryptoKey | Uint8Array",[227,265,266,271],{},[242,267,268],{},[180,269,270],{},"options.alg",[242,272,273,276],{},[180,274,275],{},"KeyManagementAlgorithm"," — required when inference fails",[227,278,279,284],{},[242,280,281],{},[180,282,283],{},"options.enc",[242,285,286,289,290],{},[180,287,288],{},"ContentEncryptionAlgorithm"," — required when ",[180,291,292],{},"alg = \"dir\"",[227,294,295,298],{},[242,296,297],{},"Others",[242,299,300,301,306],{},"See ",[302,303,305],"a",{"href":304},"#full-signature","Full signature"," below",[203,308,309,312,313,316,317,320,321,324,325,327,328,331,332,335,336,339],{},[180,310,311],{},"JWEEncryptJWK"," narrows the JWK by family: an ",[180,314,315],{},"oct"," key with a JWE symmetric ",[180,318,319],{},"alg"," (AES-KW, AES-GCM, AES-GCM-KW, AES-CBC-HMAC, PBES2, or ",[180,322,323],{},"\"dir\"","), or a public asymmetric JWK whose ",[180,326,319],{}," is RSA-OAEP (",[180,329,330],{},"JWK_RSA_Public\u003CJWK_RSA_ENC>",") or ECDH-ES (",[180,333,334],{},"JWK_EC_Public\u003CJWK_ECDH_ES>"," \u002F ",[180,337,338],{},"JWK_OKP_Public\u003CJWK_ECDH_ES>","). HMAC and other non-JWE algs are rejected at the type level.",[203,341,342,343,346],{},"Returns ",[180,344,345],{},"Promise\u003Cstring>"," — the compact JWE.",[216,348,350],{"id":349},"algorithm-inference","Algorithm inference",[203,352,353,354,356,357,359,360,362,363,366],{},"The shape of ",[180,355,258],{}," determines ",[180,358,319],{},", and then ",[180,361,319],{}," determines whether ",[180,364,365],{},"enc"," is inferable:",[221,368,369,388],{},[224,370,371],{},[227,372,373,378,383],{},[230,374,375,377],{},[180,376,258],{}," shape",[230,379,380,381],{},"Inferred ",[180,382,319],{},[230,384,385,387],{},[180,386,365],{}," default?",[237,389,390,408,428,444],{},[227,391,392,398,403],{},[242,393,394,397],{},[180,395,396],{},"string"," (password)",[242,399,400],{},[180,401,402],{},"PBES2-HS256+A128KW",[242,404,405],{},[180,406,407],{},"A128GCM",[227,409,410,418,423],{},[242,411,412,414,415,417],{},[180,413,107],{}," with ",[180,416,319],{}," field",[242,419,420],{},[180,421,422],{},"key.alg",[242,424,425,426],{},"Depends on ",[180,427,319],{},[227,429,430,438,441],{},[242,431,432,414,435],{},[180,433,434],{},"CryptoKey",[180,436,437],{},"usages: [\"encrypt\"]",[242,439,440],{},"Derived from algorithm context",[242,442,443],{},"Usually required",[227,445,446,453,457],{},[242,447,448,414,451],{},[180,449,450],{},"CryptoKey | JWK_oct",[180,452,292],{},[242,454,455],{},[180,456,323],{},[242,458,459,462],{},[207,460,461],{},"Required"," — no default",[203,464,465,466,335,468,470],{},"Pass ",[180,467,270],{},[180,469,283],{}," explicitly when inference is impossible.",[216,472,474],{"id":473},"key-shapes","Key shapes",[476,477,479],"h3",{"id":478},"password-pbes2","Password (PBES2)",[203,481,482],{},"The shortest path — unjwt derives a CEK-wrapping key via PBKDF2:",[173,484,486],{"className":175,"code":485,"language":177,"meta":178,"style":178},"const token = await encrypt({ data: \"x\" }, \"my-password\");\n\u002F\u002F Uses: alg = PBES2-HS256+A128KW, enc = A128GCM, p2c = 600_000\n",[180,487,488,522],{"__ignoreMap":178},[183,489,490,493,497,500,503,506,509,513,516,519],{"class":185,"line":186},[183,491,492],{"class":197},"const",[183,494,496],{"class":495},"suiK_"," token",[183,498,499],{"class":197}," =",[183,501,502],{"class":197}," await",[183,504,505],{"class":189}," encrypt",[183,507,508],{"class":193},"({ data: ",[183,510,512],{"class":511},"sfrk1","\"x\"",[183,514,515],{"class":193}," }, ",[183,517,518],{"class":511},"\"my-password\"",[183,520,521],{"class":193},");\n",[183,523,525],{"class":185,"line":524},2,[183,526,528],{"class":527},"sCsY4","\u002F\u002F Uses: alg = PBES2-HS256+A128KW, enc = A128GCM, p2c = 600_000\n",[203,530,531,532,535,536,539],{},"The ",[180,533,534],{},"p2s"," (salt) and ",[180,537,538],{},"p2c"," (iteration count) are written into the header so the decryptor can regenerate the same wrapping key.",[541,542,543],"tip",{},[203,544,545,550,551,557],{},[207,546,547,549],{},[180,548,538],{}," defaults to 600 000"," — the ",[302,552,556],{"href":553,"rel":554},"https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FPassword_Storage_Cheat_Sheet.html#pbkdf2",[555],"nofollow","OWASP PBKDF2 recommendation"," for HMAC-SHA256. Lower it only for legacy interop. PBKDF2 is intentionally slow, so a password-protected token takes ~tens of milliseconds to produce on a modern laptop.",[476,559,561],{"id":560},"symmetric-jwk","Symmetric JWK",[203,563,564,565,568],{},"A key generated by ",[180,566,567],{},"generateJWK(\"A256KW\")"," or similar:",[173,570,572],{"className":175,"code":571,"language":177,"meta":178,"style":178},"const aesKey = await generateJWK(\"A256KW\"); \u002F\u002F key.alg === \"A256KW\"\nconst token = await encrypt({ data: \"x\" }, aesKey); \u002F\u002F alg inferred; enc defaults to A128GCM\n",[180,573,574,600],{"__ignoreMap":178},[183,575,576,578,581,583,585,588,591,594,597],{"class":185,"line":186},[183,577,492],{"class":197},[183,579,580],{"class":495}," aesKey",[183,582,499],{"class":197},[183,584,502],{"class":197},[183,586,587],{"class":189}," generateJWK",[183,589,590],{"class":193},"(",[183,592,593],{"class":511},"\"A256KW\"",[183,595,596],{"class":193},"); ",[183,598,599],{"class":527},"\u002F\u002F key.alg === \"A256KW\"\n",[183,601,602,604,606,608,610,612,614,616,619],{"class":185,"line":524},[183,603,492],{"class":197},[183,605,496],{"class":495},[183,607,499],{"class":197},[183,609,502],{"class":197},[183,611,505],{"class":189},[183,613,508],{"class":193},[183,615,512],{"class":511},[183,617,618],{"class":193}," }, aesKey); ",[183,620,621],{"class":527},"\u002F\u002F alg inferred; enc defaults to A128GCM\n",[476,623,625],{"id":624},"asymmetric-jwk-public-key","Asymmetric JWK — public key",[203,627,628],{},"For RSA-OAEP and ECDH-ES:",[173,630,632],{"className":175,"code":631,"language":177,"meta":178,"style":178},"const { publicKey, privateKey } = await generateJWK(\"RSA-OAEP-256\");\nconst token = await encrypt({ data: \"x\" }, publicKey);\n\u002F\u002F Recipient decrypts with privateKey\n",[180,633,634,667,686],{"__ignoreMap":178},[183,635,636,638,641,644,647,650,653,656,658,660,662,665],{"class":185,"line":186},[183,637,492],{"class":197},[183,639,640],{"class":193}," { ",[183,642,643],{"class":495},"publicKey",[183,645,646],{"class":193},", ",[183,648,649],{"class":495},"privateKey",[183,651,652],{"class":193}," } ",[183,654,655],{"class":197},"=",[183,657,502],{"class":197},[183,659,587],{"class":189},[183,661,590],{"class":193},[183,663,664],{"class":511},"\"RSA-OAEP-256\"",[183,666,521],{"class":193},[183,668,669,671,673,675,677,679,681,683],{"class":185,"line":524},[183,670,492],{"class":197},[183,672,496],{"class":495},[183,674,499],{"class":197},[183,676,502],{"class":197},[183,678,505],{"class":189},[183,680,508],{"class":193},[183,682,512],{"class":511},[183,684,685],{"class":193}," }, publicKey);\n",[183,687,689],{"class":185,"line":688},3,[183,690,691],{"class":527},"\u002F\u002F Recipient decrypts with privateKey\n",[476,693,695,696],{"id":694},"direct-encryption-dir","Direct encryption — ",[180,697,698],{},"dir",[203,700,701,702,704,705,708,709,712],{},"With ",[180,703,292],{},", the provided key ",[207,706,707],{},"is"," the CEK. No wrapping happens; ",[180,710,711],{},"encryptedKey"," in the token is empty.",[173,714,716],{"className":175,"code":715,"language":177,"meta":178,"style":178},"import { generateKey } from \"unjwt\u002Fjwk\";\n\nconst cek = await generateKey(\"A256GCM\"); \u002F\u002F CryptoKey suitable as CEK for A256GCM\nconst token = await encrypt({ data: \"x\" }, cek, { alg: \"dir\", enc: \"A256GCM\" });\n",[180,717,718,735,741,765],{"__ignoreMap":178},[183,719,720,723,726,729,732],{"class":185,"line":186},[183,721,722],{"class":197},"import",[183,724,725],{"class":193}," { generateKey } ",[183,727,728],{"class":197},"from",[183,730,731],{"class":511}," \"unjwt\u002Fjwk\"",[183,733,734],{"class":193},";\n",[183,736,737],{"class":185,"line":524},[183,738,740],{"emptyLinePlaceholder":739},true,"\n",[183,742,743,745,748,750,752,755,757,760,762],{"class":185,"line":688},[183,744,492],{"class":197},[183,746,747],{"class":495}," cek",[183,749,499],{"class":197},[183,751,502],{"class":197},[183,753,754],{"class":189}," generateKey",[183,756,590],{"class":193},[183,758,759],{"class":511},"\"A256GCM\"",[183,761,596],{"class":193},[183,763,764],{"class":527},"\u002F\u002F CryptoKey suitable as CEK for A256GCM\n",[183,766,768,770,772,774,776,778,780,782,785,787,790,792],{"class":185,"line":767},4,[183,769,492],{"class":197},[183,771,496],{"class":495},[183,773,499],{"class":197},[183,775,502],{"class":197},[183,777,505],{"class":189},[183,779,508],{"class":193},[183,781,512],{"class":511},[183,783,784],{"class":193}," }, cek, { alg: ",[183,786,323],{"class":511},[183,788,789],{"class":193},", enc: ",[183,791,759],{"class":511},[183,793,794],{"class":193}," });\n",[203,796,797,798,801,802,804,805,808],{},"When passing a ",[180,799,800],{},"JWK_oct"," directly, you can hint ",[180,803,365],{}," via the non-standard ",[180,806,807],{},"jwk.enc"," field (unjwt reads it):",[173,810,812],{"className":175,"code":811,"language":177,"meta":178,"style":178},"const cekJwk = { ...(await generateJWK(\"A256GCM\")), enc: \"A256GCM\" };\nconst token = await encrypt({ data: \"x\" }, cekJwk, { alg: \"dir\" });\n",[180,813,814,847],{"__ignoreMap":178},[183,815,816,818,821,823,825,828,830,833,835,837,839,842,844],{"class":185,"line":186},[183,817,492],{"class":197},[183,819,820],{"class":495}," cekJwk",[183,822,499],{"class":197},[183,824,640],{"class":193},[183,826,827],{"class":197},"...",[183,829,590],{"class":193},[183,831,832],{"class":197},"await",[183,834,587],{"class":189},[183,836,590],{"class":193},[183,838,759],{"class":511},[183,840,841],{"class":193},")), enc: ",[183,843,759],{"class":511},[183,845,846],{"class":193}," };\n",[183,848,849,851,853,855,857,859,861,863,866,868],{"class":185,"line":524},[183,850,492],{"class":197},[183,852,496],{"class":495},[183,854,499],{"class":197},[183,856,502],{"class":197},[183,858,505],{"class":189},[183,860,508],{"class":193},[183,862,512],{"class":511},[183,864,865],{"class":193}," }, cekJwk, { alg: ",[183,867,323],{"class":511},[183,869,794],{"class":193},[203,871,872,874,875,877],{},[180,873,698],{}," produces the smallest token (the ",[180,876,711],{}," segment is empty) but requires both parties to hold the exact same CEK ahead of time.",[216,879,881,884],{"id":880},"expiresin-the-same-as-jws",[180,882,883],{},"expiresIn"," — the same as JWS",[203,886,887],{},"If the payload is a JSON object:",[173,889,891],{"className":175,"code":890,"language":177,"meta":178,"style":178},"await encrypt({ sub: \"u1\" }, key, { expiresIn: \"1h\" });\n",[180,892,893],{"__ignoreMap":178},[183,894,895,897,899,902,905,908,911],{"class":185,"line":186},[183,896,832],{"class":197},[183,898,505],{"class":189},[183,900,901],{"class":193},"({ sub: ",[183,903,904],{"class":511},"\"u1\"",[183,906,907],{"class":193}," }, key, { expiresIn: ",[183,909,910],{"class":511},"\"1h\"",[183,912,794],{"class":193},[203,914,915,916,646,919,646,922,646,925,646,928,646,931,646,934,646,937,214],{},"Accepted forms: ",[180,917,918],{},"30",[180,920,921],{},"\"30s\"",[180,923,924],{},"\"10m\"",[180,926,927],{},"\"2h\"",[180,929,930],{},"\"7D\"",[180,932,933],{},"\"1W\"",[180,935,936],{},"\"3M\"",[180,938,939],{},"\"1Y\"",[216,941,943],{"id":942},"custom-protected-header","Custom protected header",[203,945,946],{},"The JWE protected header is part of the AAD (Additional Authenticated Data) — anything you put there is bound to the ciphertext and can't be altered without invalidating the tag.",[173,948,950],{"className":175,"code":949,"language":177,"meta":178,"style":178},"const token = await encrypt({ sub: \"u1\" }, key, {\n  protectedHeader: {\n    kid: \"my-key\",\n    typ: \"JWE\", \u002F\u002F default for object payloads\n    cty: \"application\u002Fjson\",\n  },\n});\n",[180,951,952,971,976,987,1000,1011,1017],{"__ignoreMap":178},[183,953,954,956,958,960,962,964,966,968],{"class":185,"line":186},[183,955,492],{"class":197},[183,957,496],{"class":495},[183,959,499],{"class":197},[183,961,502],{"class":197},[183,963,505],{"class":189},[183,965,901],{"class":193},[183,967,904],{"class":511},[183,969,970],{"class":193}," }, key, {\n",[183,972,973],{"class":185,"line":524},[183,974,975],{"class":193},"  protectedHeader: {\n",[183,977,978,981,984],{"class":185,"line":688},[183,979,980],{"class":193},"    kid: ",[183,982,983],{"class":511},"\"my-key\"",[183,985,986],{"class":193},",\n",[183,988,989,992,995,997],{"class":185,"line":767},[183,990,991],{"class":193},"    typ: ",[183,993,994],{"class":511},"\"JWE\"",[183,996,646],{"class":193},[183,998,999],{"class":527},"\u002F\u002F default for object payloads\n",[183,1001,1003,1006,1009],{"class":185,"line":1002},5,[183,1004,1005],{"class":193},"    cty: ",[183,1007,1008],{"class":511},"\"application\u002Fjson\"",[183,1010,986],{"class":193},[183,1012,1014],{"class":185,"line":1013},6,[183,1015,1016],{"class":193},"  },\n",[183,1018,1020],{"class":185,"line":1019},7,[183,1021,1022],{"class":193},"});\n",[203,1024,1025,1026,1029],{},"The library manages these fields and rejects them in ",[180,1027,1028],{},"protectedHeader",":",[1031,1032,1033,1046,1055,1062],"ul",{},[1034,1035,1036,646,1038,1040,1041,1043,1044,214],"li",{},[180,1037,319],{},[180,1039,365],{}," — set via ",[180,1042,270],{},"\u002F",[180,1045,283],{},[1034,1047,1048,646,1051,1054],{},[180,1049,1050],{},"iv",[180,1052,1053],{},"tag"," — computed during encryption.",[1034,1056,1057,646,1059,1061],{},[180,1058,534],{},[180,1060,538],{}," — set for PBES2.",[1034,1063,1064,646,1067,646,1070,1073],{},[180,1065,1066],{},"epk",[180,1068,1069],{},"apu",[180,1071,1072],{},"apv"," — set for ECDH-ES.",[216,1075,1077],{"id":1076},"custom-cek-iv","Custom CEK \u002F IV",[203,1079,1080],{},"For test reproducibility, deterministic benchmarks, or interop scenarios:",[173,1082,1084],{"className":175,"code":1083,"language":177,"meta":178,"style":178},"import { secureRandomBytes } from \"unjwt\u002Futils\";\n\nconst token = await encrypt({ data: \"x\" }, key, {\n  cek: secureRandomBytes(32), \u002F\u002F supply your own CEK\n  contentEncryptionIV: secureRandomBytes(12), \u002F\u002F supply your own IV\n});\n",[180,1085,1086,1100,1104,1122,1141,1158],{"__ignoreMap":178},[183,1087,1088,1090,1093,1095,1098],{"class":185,"line":186},[183,1089,722],{"class":197},[183,1091,1092],{"class":193}," { secureRandomBytes } ",[183,1094,728],{"class":197},[183,1096,1097],{"class":511}," \"unjwt\u002Futils\"",[183,1099,734],{"class":193},[183,1101,1102],{"class":185,"line":524},[183,1103,740],{"emptyLinePlaceholder":739},[183,1105,1106,1108,1110,1112,1114,1116,1118,1120],{"class":185,"line":688},[183,1107,492],{"class":197},[183,1109,496],{"class":495},[183,1111,499],{"class":197},[183,1113,502],{"class":197},[183,1115,505],{"class":189},[183,1117,508],{"class":193},[183,1119,512],{"class":511},[183,1121,970],{"class":193},[183,1123,1124,1127,1130,1132,1135,1138],{"class":185,"line":767},[183,1125,1126],{"class":193},"  cek: ",[183,1128,1129],{"class":189},"secureRandomBytes",[183,1131,590],{"class":193},[183,1133,1134],{"class":495},"32",[183,1136,1137],{"class":193},"), ",[183,1139,1140],{"class":527},"\u002F\u002F supply your own CEK\n",[183,1142,1143,1146,1148,1150,1153,1155],{"class":185,"line":1002},[183,1144,1145],{"class":193},"  contentEncryptionIV: ",[183,1147,1129],{"class":189},[183,1149,590],{"class":193},[183,1151,1152],{"class":495},"12",[183,1154,1137],{"class":193},[183,1156,1157],{"class":527},"\u002F\u002F supply your own IV\n",[183,1159,1160],{"class":185,"line":1013},[183,1161,1022],{"class":193},[1163,1164,1165],"warning",{},[203,1166,1167,1170],{},[207,1168,1169],{},"Never reuse"," a CEK or IV across messages in production. The primary purpose of these options is testability. In normal use, let unjwt generate fresh random values.",[216,1172,1174],{"id":1173},"pbes2-parameters","PBES2 parameters",[203,1176,1177,1178,1180],{},"Override ",[180,1179,538],{}," or provide a fixed salt:",[173,1182,1184],{"className":175,"code":1183,"language":177,"meta":178,"style":178},"const token = await encrypt({ data: \"x\" }, \"password\", {\n  p2s: secureRandomBytes(16),\n  p2c: 100_000, \u002F\u002F lower — only for legacy interop\n});\n",[180,1185,1186,1210,1225,1238],{"__ignoreMap":178},[183,1187,1188,1190,1192,1194,1196,1198,1200,1202,1204,1207],{"class":185,"line":186},[183,1189,492],{"class":197},[183,1191,496],{"class":495},[183,1193,499],{"class":197},[183,1195,502],{"class":197},[183,1197,505],{"class":189},[183,1199,508],{"class":193},[183,1201,512],{"class":511},[183,1203,515],{"class":193},[183,1205,1206],{"class":511},"\"password\"",[183,1208,1209],{"class":193},", {\n",[183,1211,1212,1215,1217,1219,1222],{"class":185,"line":524},[183,1213,1214],{"class":193},"  p2s: ",[183,1216,1129],{"class":189},[183,1218,590],{"class":193},[183,1220,1221],{"class":495},"16",[183,1223,1224],{"class":193},"),\n",[183,1226,1227,1230,1233,1235],{"class":185,"line":688},[183,1228,1229],{"class":193},"  p2c: ",[183,1231,1232],{"class":495},"100_000",[183,1234,646],{"class":193},[183,1236,1237],{"class":527},"\u002F\u002F lower — only for legacy interop\n",[183,1239,1240],{"class":185,"line":767},[183,1241,1022],{"class":193},[203,1243,1244,1245,1247,1248,1254],{},"Raising ",[180,1246,538],{}," on the sender side means proportionally more CPU for the decryptor too — unjwt enforces a ceiling by default (see ",[302,1249,1251],{"href":1250},"\u002Fjwt\u002Fjwe\u002Fdecrypting#pbes2-dos-protection",[180,1252,1253],{},"maxIterations"," on decrypt).",[216,1256,1258],{"id":1257},"ecdh-es-parameters","ECDH-ES parameters",[203,1260,1261,1262,335,1265,1268],{},"For ",[180,1263,1264],{},"ECDH-ES",[180,1266,1267],{},"ECDH-ES+A*KW"," keys:",[173,1270,1272],{"className":175,"code":1271,"language":177,"meta":178,"style":178},"const token = await encrypt({ data: \"x\" }, ecPublicKey, {\n  enc: \"A256GCM\", \u002F\u002F required at top level for bare \"ECDH-ES\"\n  ecdh: {\n    ephemeralKey: senderEphemeralKeypair, \u002F\u002F override if you need a specific key\n    partyUInfo: new TextEncoder().encode(\"alice@example.com\"),\n    partyVInfo: new TextEncoder().encode(\"bob@example.com\"),\n  },\n});\n",[180,1273,1274,1293,1305,1310,1318,1342,1362,1366],{"__ignoreMap":178},[183,1275,1276,1278,1280,1282,1284,1286,1288,1290],{"class":185,"line":186},[183,1277,492],{"class":197},[183,1279,496],{"class":495},[183,1281,499],{"class":197},[183,1283,502],{"class":197},[183,1285,505],{"class":189},[183,1287,508],{"class":193},[183,1289,512],{"class":511},[183,1291,1292],{"class":193}," }, ecPublicKey, {\n",[183,1294,1295,1298,1300,1302],{"class":185,"line":524},[183,1296,1297],{"class":193},"  enc: ",[183,1299,759],{"class":511},[183,1301,646],{"class":193},[183,1303,1304],{"class":527},"\u002F\u002F required at top level for bare \"ECDH-ES\"\n",[183,1306,1307],{"class":185,"line":688},[183,1308,1309],{"class":193},"  ecdh: {\n",[183,1311,1312,1315],{"class":185,"line":767},[183,1313,1314],{"class":193},"    ephemeralKey: senderEphemeralKeypair, ",[183,1316,1317],{"class":527},"\u002F\u002F override if you need a specific key\n",[183,1319,1320,1323,1326,1329,1332,1335,1337,1340],{"class":185,"line":1002},[183,1321,1322],{"class":193},"    partyUInfo: ",[183,1324,1325],{"class":197},"new",[183,1327,1328],{"class":189}," TextEncoder",[183,1330,1331],{"class":193},"().",[183,1333,1334],{"class":189},"encode",[183,1336,590],{"class":193},[183,1338,1339],{"class":511},"\"alice@example.com\"",[183,1341,1224],{"class":193},[183,1343,1344,1347,1349,1351,1353,1355,1357,1360],{"class":185,"line":1013},[183,1345,1346],{"class":193},"    partyVInfo: ",[183,1348,1325],{"class":197},[183,1350,1328],{"class":189},[183,1352,1331],{"class":193},[183,1354,1334],{"class":189},[183,1356,590],{"class":193},[183,1358,1359],{"class":511},"\"bob@example.com\"",[183,1361,1224],{"class":193},[183,1363,1364],{"class":185,"line":1019},[183,1365,1016],{"class":193},[183,1367,1369],{"class":185,"line":1368},8,[183,1370,1022],{"class":193},[203,1372,1373,335,1376,1379,1380,1385],{},[180,1374,1375],{},"partyUInfo",[180,1377,1378],{},"partyVInfo"," bind the derived key to specific sender\u002Frecipient identities (part of ",[302,1381,1384],{"href":1382,"rel":1383},"https:\u002F\u002Fnvlpubs.nist.gov\u002Fnistpubs\u002FSpecialPublications\u002FNIST.SP.800-56Ar3.pdf",[555],"NIST SP 800-56A"," Concat KDF). They're optional, but they're how you prevent cross-context key reuse.",[203,1387,1388,1389,214],{},"Full pattern: ",[302,1390,1391],{"href":73},"ECDH-ES →",[216,1393,305],{"id":1394},"full-signature",[173,1396,1398],{"className":175,"code":1397,"language":177,"meta":178,"style":178},"interface JWEEncryptOptions {\n  alg?: KeyManagementAlgorithm;\n  enc?: ContentEncryptionAlgorithm;\n  currentDate?: Date;\n  expiresIn?: ExpiresIn;\n  expiresAt?: Date;\n  notBeforeIn?: ExpiresIn;\n  notBeforeAt?: Date;\n  protectedHeader?: StrictOmit\u003C\n    JWEHeaderParameters,\n    \"alg\" | \"enc\" | \"iv\" | \"tag\" | \"p2s\" | \"p2c\" | \"epk\" | \"apu\" | \"apv\"\n  >;\n  keyManagementIV?: Uint8Array\u003CArrayBuffer>;\n  p2s?: Uint8Array\u003CArrayBuffer>;\n  p2c?: number;\n  ecdh?: {\n    ephemeralKey?:\n      | CryptoKey\n      | JWK_EC_Private\n      | CryptoKeyPair\n      | {\n          publicKey: CryptoKey | JWK_EC_Public;\n          privateKey: CryptoKey | JWK_EC_Private;\n        };\n    partyUInfo?: Uint8Array\u003CArrayBuffer>;\n    partyVInfo?: Uint8Array\u003CArrayBuffer>;\n  };\n  cek?: Uint8Array\u003CArrayBuffer>;\n  contentEncryptionIV?: Uint8Array\u003CArrayBuffer>;\n}\n",[180,1399,1400,1411,1425,1437,1449,1461,1472,1483,1494,1508,1516,1563,1569,1589,1605,1618,1628,1637,1646,1654,1662,1669,1687,1704,1710,1726,1742,1748,1764,1780],{"__ignoreMap":178},[183,1401,1402,1405,1408],{"class":185,"line":186},[183,1403,1404],{"class":197},"interface",[183,1406,1407],{"class":189}," JWEEncryptOptions",[183,1409,1410],{"class":193}," {\n",[183,1412,1413,1417,1420,1423],{"class":185,"line":524},[183,1414,1416],{"class":1415},"sQHwn","  alg",[183,1418,1419],{"class":197},"?:",[183,1421,1422],{"class":189}," KeyManagementAlgorithm",[183,1424,734],{"class":193},[183,1426,1427,1430,1432,1435],{"class":185,"line":688},[183,1428,1429],{"class":1415},"  enc",[183,1431,1419],{"class":197},[183,1433,1434],{"class":189}," ContentEncryptionAlgorithm",[183,1436,734],{"class":193},[183,1438,1439,1442,1444,1447],{"class":185,"line":767},[183,1440,1441],{"class":1415},"  currentDate",[183,1443,1419],{"class":197},[183,1445,1446],{"class":189}," Date",[183,1448,734],{"class":193},[183,1450,1451,1454,1456,1459],{"class":185,"line":1002},[183,1452,1453],{"class":1415},"  expiresIn",[183,1455,1419],{"class":197},[183,1457,1458],{"class":189}," ExpiresIn",[183,1460,734],{"class":193},[183,1462,1463,1466,1468,1470],{"class":185,"line":1013},[183,1464,1465],{"class":1415},"  expiresAt",[183,1467,1419],{"class":197},[183,1469,1446],{"class":189},[183,1471,734],{"class":193},[183,1473,1474,1477,1479,1481],{"class":185,"line":1019},[183,1475,1476],{"class":1415},"  notBeforeIn",[183,1478,1419],{"class":197},[183,1480,1458],{"class":189},[183,1482,734],{"class":193},[183,1484,1485,1488,1490,1492],{"class":185,"line":1368},[183,1486,1487],{"class":1415},"  notBeforeAt",[183,1489,1419],{"class":197},[183,1491,1446],{"class":189},[183,1493,734],{"class":193},[183,1495,1497,1500,1502,1505],{"class":185,"line":1496},9,[183,1498,1499],{"class":1415},"  protectedHeader",[183,1501,1419],{"class":197},[183,1503,1504],{"class":189}," StrictOmit",[183,1506,1507],{"class":193},"\u003C\n",[183,1509,1511,1514],{"class":185,"line":1510},10,[183,1512,1513],{"class":189},"    JWEHeaderParameters",[183,1515,986],{"class":193},[183,1517,1519,1522,1525,1528,1530,1533,1535,1538,1540,1543,1545,1548,1550,1553,1555,1558,1560],{"class":185,"line":1518},11,[183,1520,1521],{"class":511},"    \"alg\"",[183,1523,1524],{"class":197}," |",[183,1526,1527],{"class":511}," \"enc\"",[183,1529,1524],{"class":197},[183,1531,1532],{"class":511}," \"iv\"",[183,1534,1524],{"class":197},[183,1536,1537],{"class":511}," \"tag\"",[183,1539,1524],{"class":197},[183,1541,1542],{"class":511}," \"p2s\"",[183,1544,1524],{"class":197},[183,1546,1547],{"class":511}," \"p2c\"",[183,1549,1524],{"class":197},[183,1551,1552],{"class":511}," \"epk\"",[183,1554,1524],{"class":197},[183,1556,1557],{"class":511}," \"apu\"",[183,1559,1524],{"class":197},[183,1561,1562],{"class":511}," \"apv\"\n",[183,1564,1566],{"class":185,"line":1565},12,[183,1567,1568],{"class":193},"  >;\n",[183,1570,1572,1575,1577,1580,1583,1586],{"class":185,"line":1571},13,[183,1573,1574],{"class":1415},"  keyManagementIV",[183,1576,1419],{"class":197},[183,1578,1579],{"class":189}," Uint8Array",[183,1581,1582],{"class":193},"\u003C",[183,1584,1585],{"class":189},"ArrayBuffer",[183,1587,1588],{"class":193},">;\n",[183,1590,1592,1595,1597,1599,1601,1603],{"class":185,"line":1591},14,[183,1593,1594],{"class":1415},"  p2s",[183,1596,1419],{"class":197},[183,1598,1579],{"class":189},[183,1600,1582],{"class":193},[183,1602,1585],{"class":189},[183,1604,1588],{"class":193},[183,1606,1608,1611,1613,1616],{"class":185,"line":1607},15,[183,1609,1610],{"class":1415},"  p2c",[183,1612,1419],{"class":197},[183,1614,1615],{"class":495}," number",[183,1617,734],{"class":193},[183,1619,1621,1624,1626],{"class":185,"line":1620},16,[183,1622,1623],{"class":1415},"  ecdh",[183,1625,1419],{"class":197},[183,1627,1410],{"class":193},[183,1629,1631,1634],{"class":185,"line":1630},17,[183,1632,1633],{"class":1415},"    ephemeralKey",[183,1635,1636],{"class":197},"?:\n",[183,1638,1640,1643],{"class":185,"line":1639},18,[183,1641,1642],{"class":197},"      |",[183,1644,1645],{"class":189}," CryptoKey\n",[183,1647,1649,1651],{"class":185,"line":1648},19,[183,1650,1642],{"class":197},[183,1652,1653],{"class":189}," JWK_EC_Private\n",[183,1655,1657,1659],{"class":185,"line":1656},20,[183,1658,1642],{"class":197},[183,1660,1661],{"class":189}," CryptoKeyPair\n",[183,1663,1665,1667],{"class":185,"line":1664},21,[183,1666,1642],{"class":197},[183,1668,1410],{"class":193},[183,1670,1672,1675,1677,1680,1682,1685],{"class":185,"line":1671},22,[183,1673,1674],{"class":1415},"          publicKey",[183,1676,1029],{"class":197},[183,1678,1679],{"class":189}," CryptoKey",[183,1681,1524],{"class":197},[183,1683,1684],{"class":189}," JWK_EC_Public",[183,1686,734],{"class":193},[183,1688,1690,1693,1695,1697,1699,1702],{"class":185,"line":1689},23,[183,1691,1692],{"class":1415},"          privateKey",[183,1694,1029],{"class":197},[183,1696,1679],{"class":189},[183,1698,1524],{"class":197},[183,1700,1701],{"class":189}," JWK_EC_Private",[183,1703,734],{"class":193},[183,1705,1707],{"class":185,"line":1706},24,[183,1708,1709],{"class":193},"        };\n",[183,1711,1713,1716,1718,1720,1722,1724],{"class":185,"line":1712},25,[183,1714,1715],{"class":1415},"    partyUInfo",[183,1717,1419],{"class":197},[183,1719,1579],{"class":189},[183,1721,1582],{"class":193},[183,1723,1585],{"class":189},[183,1725,1588],{"class":193},[183,1727,1729,1732,1734,1736,1738,1740],{"class":185,"line":1728},26,[183,1730,1731],{"class":1415},"    partyVInfo",[183,1733,1419],{"class":197},[183,1735,1579],{"class":189},[183,1737,1582],{"class":193},[183,1739,1585],{"class":189},[183,1741,1588],{"class":193},[183,1743,1745],{"class":185,"line":1744},27,[183,1746,1747],{"class":193},"  };\n",[183,1749,1751,1754,1756,1758,1760,1762],{"class":185,"line":1750},28,[183,1752,1753],{"class":1415},"  cek",[183,1755,1419],{"class":197},[183,1757,1579],{"class":189},[183,1759,1582],{"class":193},[183,1761,1585],{"class":189},[183,1763,1588],{"class":193},[183,1765,1767,1770,1772,1774,1776,1778],{"class":185,"line":1766},29,[183,1768,1769],{"class":1415},"  contentEncryptionIV",[183,1771,1419],{"class":197},[183,1773,1579],{"class":189},[183,1775,1582],{"class":193},[183,1777,1585],{"class":189},[183,1779,1588],{"class":193},[183,1781,1783],{"class":185,"line":1782},30,[183,1784,1785],{"class":193},"}\n",[216,1787,1789],{"id":1788},"see-also","See also",[1031,1791,1792,1798,1809,1814],{},[1034,1793,1794,1797],{},[302,1795,1796],{"href":65},"Decrypting →"," — the consumer side.",[1034,1799,1800,1803,1804,1806,1807,214],{},[302,1801,1802],{"href":76},"Algorithms →"," — picking ",[180,1805,319],{}," and ",[180,1808,365],{},[1034,1810,1811,1813],{},[302,1812,1391],{"href":73}," — end-to-end encryption.",[1034,1815,1816,1819],{},[302,1817,1818],{"href":69},"Multi-recipient →"," — one ciphertext, many recipients.",[1821,1822,1823],"style",{},"html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}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 .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}",{"title":178,"searchDepth":524,"depth":524,"links":1825},[1826,1827,1828,1835,1837,1838,1839,1840,1841,1842],{"id":218,"depth":524,"text":219},{"id":349,"depth":524,"text":350},{"id":473,"depth":524,"text":474,"children":1829},[1830,1831,1832,1833],{"id":478,"depth":688,"text":479},{"id":560,"depth":688,"text":561},{"id":624,"depth":688,"text":625},{"id":694,"depth":688,"text":1834},"Direct encryption — dir",{"id":880,"depth":524,"text":1836},"expiresIn — the same as JWS",{"id":942,"depth":524,"text":943},{"id":1076,"depth":524,"text":1077},{"id":1173,"depth":524,"text":1174},{"id":1257,"depth":524,"text":1258},{"id":1394,"depth":524,"text":305},{"id":1788,"depth":524,"text":1789},"md",{},{},{"title":60,"description":178},"k227WhzHgKk7iq2aYG1NDx6fMPVeT2-KVOjmv8ljuzw",[1849,1850],{"title":53,"path":54,"stem":55,"description":178,"icon":58,"children":-1},{"title":64,"path":65,"stem":66,"description":178,"children":-1},1776888561401]