[{"data":1,"prerenderedAt":1314},["ShallowReactive",2],{"navigation":3,"-jwt-jwe-multi-recipient":167,"-jwt-jwe-multi-recipient-surround":1311},[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":68,"body":169,"description":197,"extension":1306,"meta":1307,"navigation":1308,"path":69,"seo":1309,"stem":70,"__hash__":1310},"content\u002F1.JWT\u002F2.JWE\u002F3.multi-recipient.md",{"type":170,"value":171,"toc":1289},"minimark",[172,176,191,395,409,412,434,445,452,652,655,660,749,753,780,783,798,802,809,873,888,892,906,912,985,994,998,1009,1013,1023,1027,1044,1065,1069,1076,1106,1110,1116,1175,1182,1186,1219,1223,1230,1285],[173,174,175],"p",{},"When a single encrypted payload needs to reach more than one recipient — a team document, a broadcast message, a fanned-out webhook — the compact serialization isn't enough. It can only carry one encrypted CEK.",[173,177,178,185,186,190],{},[179,180,184],"a",{"href":181,"rel":182},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc7516#section-7.2",[183],"nofollow","RFC 7516 §7.2"," defines the ",[187,188,189],"strong",{},"General JSON Serialization",":",[192,193,198],"pre",{"className":194,"code":195,"language":196,"meta":197,"style":197},"language-json shiki shiki-themes github-light github-dark github-dark","{\n  \"protected\": \"\u003Cbase64url of shared protected header>\",\n  \"unprotected\": { \"kid-root\": \"2025-q1\" },\n  \"recipients\": [\n    { \"header\": { \"alg\": \"RSA-OAEP-256\", \"kid\": \"alice\" }, \"encrypted_key\": \"...\" },\n    { \"header\": { \"alg\": \"ECDH-ES+A256KW\", \"kid\": \"bob\", \"epk\": {...} }, \"encrypted_key\": \"...\" }\n  ],\n  \"iv\": \"...\",\n  \"ciphertext\": \"...\",\n  \"tag\": \"...\"\n}\n","json","",[199,200,201,210,227,247,256,299,348,354,366,378,389],"code",{"__ignoreMap":197},[202,203,206],"span",{"class":204,"line":205},"line",1,[202,207,209],{"class":208},"slsVL","{\n",[202,211,213,217,220,224],{"class":204,"line":212},2,[202,214,216],{"class":215},"suiK_","  \"protected\"",[202,218,219],{"class":208},": ",[202,221,223],{"class":222},"sfrk1","\"\u003Cbase64url of shared protected header>\"",[202,225,226],{"class":208},",\n",[202,228,230,233,236,239,241,244],{"class":204,"line":229},3,[202,231,232],{"class":215},"  \"unprotected\"",[202,234,235],{"class":208},": { ",[202,237,238],{"class":215},"\"kid-root\"",[202,240,219],{"class":208},[202,242,243],{"class":222},"\"2025-q1\"",[202,245,246],{"class":208}," },\n",[202,248,250,253],{"class":204,"line":249},4,[202,251,252],{"class":215},"  \"recipients\"",[202,254,255],{"class":208},": [\n",[202,257,259,262,265,267,270,272,275,278,281,283,286,289,292,294,297],{"class":204,"line":258},5,[202,260,261],{"class":208},"    { ",[202,263,264],{"class":215},"\"header\"",[202,266,235],{"class":208},[202,268,269],{"class":215},"\"alg\"",[202,271,219],{"class":208},[202,273,274],{"class":222},"\"RSA-OAEP-256\"",[202,276,277],{"class":208},", ",[202,279,280],{"class":215},"\"kid\"",[202,282,219],{"class":208},[202,284,285],{"class":222},"\"alice\"",[202,287,288],{"class":208}," }, ",[202,290,291],{"class":215},"\"encrypted_key\"",[202,293,219],{"class":208},[202,295,296],{"class":222},"\"...\"",[202,298,246],{"class":208},[202,300,302,304,306,308,310,312,315,317,319,321,324,326,329,332,336,339,341,343,345],{"class":204,"line":301},6,[202,303,261],{"class":208},[202,305,264],{"class":215},[202,307,235],{"class":208},[202,309,269],{"class":215},[202,311,219],{"class":208},[202,313,314],{"class":222},"\"ECDH-ES+A256KW\"",[202,316,277],{"class":208},[202,318,280],{"class":215},[202,320,219],{"class":208},[202,322,323],{"class":222},"\"bob\"",[202,325,277],{"class":208},[202,327,328],{"class":215},"\"epk\"",[202,330,331],{"class":208},": {",[202,333,335],{"class":334},"sVAnh","...",[202,337,338],{"class":208},"} }, ",[202,340,291],{"class":215},[202,342,219],{"class":208},[202,344,296],{"class":222},[202,346,347],{"class":208}," }\n",[202,349,351],{"class":204,"line":350},7,[202,352,353],{"class":208},"  ],\n",[202,355,357,360,362,364],{"class":204,"line":356},8,[202,358,359],{"class":215},"  \"iv\"",[202,361,219],{"class":208},[202,363,296],{"class":222},[202,365,226],{"class":208},[202,367,369,372,374,376],{"class":204,"line":368},9,[202,370,371],{"class":215},"  \"ciphertext\"",[202,373,219],{"class":208},[202,375,296],{"class":222},[202,377,226],{"class":208},[202,379,381,384,386],{"class":204,"line":380},10,[202,382,383],{"class":215},"  \"tag\"",[202,385,219],{"class":208},[202,387,388],{"class":222},"\"...\"\n",[202,390,392],{"class":204,"line":391},11,[202,393,394],{"class":208},"}\n",[173,396,397,400,401,404,405,408],{},[187,398,399],{},"One shared CEK"," encrypts the payload once. The CEK is then ",[187,402,403],{},"wrapped per recipient"," with their own key and ",[199,406,407],{},"alg",". Each recipient unwraps their own entry; the shared ciphertext is the same for everyone.",[173,410,411],{},"unjwt exposes two functions for this:",[413,414,415,425],"ul",{},[416,417,418,424],"li",{},[179,419,421],{"href":420},"#encryptmulti",[199,422,423],{},"encryptMulti()"," — produce the General serialization.",[416,426,427,433],{},[179,428,430],{"href":429},"#decryptmulti",[199,431,432],{},"decryptMulti()"," — unwrap using one recipient's key, return the shared payload.",[173,435,436,437,440,441,444],{},"Both importable from ",[199,438,439],{},"unjwt\u002Fjwe"," (or ",[199,442,443],{},"unjwt",").",[446,447,449],"h2",{"id":448},"encryptmulti",[199,450,451],{},"encryptMulti",[192,453,458],{"className":454,"code":455,"filename":456,"language":457,"meta":197,"style":197},"language-ts shiki shiki-themes github-light github-dark github-dark","import { encryptMulti } from \"unjwt\u002Fjwe\";\n\nconst jwe = await encryptMulti(\n  { doc: \"quarterly numbers\", quarter: \"Q1\" },\n  [\n    { key: aliceRsaPublicJwk }, \u002F\u002F alg inferred → RSA-OAEP-256\n    { key: bobEcdhPublicJwk }, \u002F\u002F alg inferred → ECDH-ES+A256KW\n    { key: sharedAesKwJwk, header: { \"x-route\": \"eu\" } }, \u002F\u002F alg → A256KW, extra per-recipient header\n  ],\n  {\n    enc: \"A256GCM\",\n    expiresIn: \"1h\",\n    sharedUnprotectedHeader: { \"kid-set\": \"2025-q1\" }, \u002F\u002F top-level `unprotected`\n    aad: new TextEncoder().encode(\"doc-id:42\"), \u002F\u002F external AAD binding (optional)\n  },\n);\n","encrypt-multi.ts","ts",[199,459,460,478,484,505,521,526,535,543,562,566,571,581,592,610,640,646],{"__ignoreMap":197},[202,461,462,466,469,472,475],{"class":204,"line":205},[202,463,465],{"class":464},"so5gQ","import",[202,467,468],{"class":208}," { encryptMulti } ",[202,470,471],{"class":464},"from",[202,473,474],{"class":222}," \"unjwt\u002Fjwe\"",[202,476,477],{"class":208},";\n",[202,479,480],{"class":204,"line":212},[202,481,483],{"emptyLinePlaceholder":482},true,"\n",[202,485,486,489,492,495,498,502],{"class":204,"line":229},[202,487,488],{"class":464},"const",[202,490,491],{"class":215}," jwe",[202,493,494],{"class":464}," =",[202,496,497],{"class":464}," await",[202,499,501],{"class":500},"shcOC"," encryptMulti",[202,503,504],{"class":208},"(\n",[202,506,507,510,513,516,519],{"class":204,"line":249},[202,508,509],{"class":208},"  { doc: ",[202,511,512],{"class":222},"\"quarterly numbers\"",[202,514,515],{"class":208},", quarter: ",[202,517,518],{"class":222},"\"Q1\"",[202,520,246],{"class":208},[202,522,523],{"class":204,"line":258},[202,524,525],{"class":208},"  [\n",[202,527,528,531],{"class":204,"line":301},[202,529,530],{"class":208},"    { key: aliceRsaPublicJwk }, ",[202,532,534],{"class":533},"sCsY4","\u002F\u002F alg inferred → RSA-OAEP-256\n",[202,536,537,540],{"class":204,"line":350},[202,538,539],{"class":208},"    { key: bobEcdhPublicJwk }, ",[202,541,542],{"class":533},"\u002F\u002F alg inferred → ECDH-ES+A256KW\n",[202,544,545,548,551,553,556,559],{"class":204,"line":356},[202,546,547],{"class":208},"    { key: sharedAesKwJwk, header: { ",[202,549,550],{"class":222},"\"x-route\"",[202,552,219],{"class":208},[202,554,555],{"class":222},"\"eu\"",[202,557,558],{"class":208}," } }, ",[202,560,561],{"class":533},"\u002F\u002F alg → A256KW, extra per-recipient header\n",[202,563,564],{"class":204,"line":368},[202,565,353],{"class":208},[202,567,568],{"class":204,"line":380},[202,569,570],{"class":208},"  {\n",[202,572,573,576,579],{"class":204,"line":391},[202,574,575],{"class":208},"    enc: ",[202,577,578],{"class":222},"\"A256GCM\"",[202,580,226],{"class":208},[202,582,584,587,590],{"class":204,"line":583},12,[202,585,586],{"class":208},"    expiresIn: ",[202,588,589],{"class":222},"\"1h\"",[202,591,226],{"class":208},[202,593,595,598,601,603,605,607],{"class":204,"line":594},13,[202,596,597],{"class":208},"    sharedUnprotectedHeader: { ",[202,599,600],{"class":222},"\"kid-set\"",[202,602,219],{"class":208},[202,604,243],{"class":222},[202,606,288],{"class":208},[202,608,609],{"class":533},"\u002F\u002F top-level `unprotected`\n",[202,611,613,616,619,622,625,628,631,634,637],{"class":204,"line":612},14,[202,614,615],{"class":208},"    aad: ",[202,617,618],{"class":464},"new",[202,620,621],{"class":500}," TextEncoder",[202,623,624],{"class":208},"().",[202,626,627],{"class":500},"encode",[202,629,630],{"class":208},"(",[202,632,633],{"class":222},"\"doc-id:42\"",[202,635,636],{"class":208},"), ",[202,638,639],{"class":533},"\u002F\u002F external AAD binding (optional)\n",[202,641,643],{"class":204,"line":642},15,[202,644,645],{"class":208},"  },\n",[202,647,649],{"class":204,"line":648},16,[202,650,651],{"class":208},");\n",[173,653,654],{},"The returned value is a plain JSON object — stringify it before sending over the wire.",[656,657,659],"h3",{"id":658},"per-recipient-fields","Per-recipient fields",[661,662,663,676],"table",{},[664,665,666],"thead",{},[667,668,669,673],"tr",{},[670,671,672],"th",{},"Field",[670,674,675],{},"Role",[677,678,679,696,716,726,739],"tbody",{},[667,680,681,687],{},[682,683,684],"td",{},[199,685,686],{},"key",[682,688,689,690],{},"Recipient's key. ",[187,691,692,695],{},[199,693,694],{},"key.alg"," is required.",[667,697,698,703],{},[682,699,700],{},[199,701,702],{},"header",[682,704,705,706,708,709,711,712,715],{},"Fields in the per-recipient ",[199,707,702],{},". Cannot set ",[199,710,407],{},"\u002F",[199,713,714],{},"enc"," here.",[667,717,718,723],{},[682,719,720],{},[199,721,722],{},"ecdh",[682,724,725],{},"ECDH-ES overrides (ephemeral key, partyUInfo, partyVInfo).",[667,727,728,736],{},[682,729,730,277,733],{},[199,731,732],{},"p2s",[199,734,735],{},"p2c",[682,737,738],{},"PBES2 parameters — only meaningful for a PBES2-keyed recipient.",[667,740,741,746],{},[682,742,743],{},[199,744,745],{},"keyManagementIV",[682,747,748],{},"AES-GCMKW IV override.",[656,750,752],{"id":751},"forbidden-algorithms","Forbidden algorithms",[173,754,755,758,759,762,763,766,767,770,771,775,776,779],{},[199,756,757],{},"dir"," and bare ",[199,760,761],{},"ECDH-ES"," (without ",[199,764,765],{},"+A*KW",") are ",[187,768,769],{},"forbidden"," in a multi-recipient envelope. Both require the recipient's key to ",[772,773,774],"em",{},"be"," the CEK — which can't be shared across multiple recipients without collapsing their security. Attempting either throws ",[199,777,778],{},"ERR_JWE_ALG_FORBIDDEN_IN_MULTI",".",[173,781,782],{},"The fix is to use the key-wrap variants instead:",[413,784,785],{},[416,786,787,790,791,790,794,797],{},[199,788,789],{},"ECDH-ES+A128KW"," \u002F ",[199,792,793],{},"+A192KW",[199,795,796],{},"+A256KW"," — derives a KEK per recipient, wraps the shared CEK with it.",[656,799,801],{"id":800},"three-header-tiers","Three header tiers",[173,803,804,805,808],{},"A multi-recipient JWE has ",[187,806,807],{},"three"," places a header field can live:",[810,811,813,834,850],"steps",{"level":812},"4",[814,815,816,821,822,277,824,277,827,830,831,779],"h4",{},[187,817,818],{},[199,819,820],{},"protected"," — shared, signed-over (part of AAD). Contains ",[199,823,714],{},[199,825,826],{},"typ",[199,828,829],{},"cty",", and any custom fields you pass in ",[199,832,833],{},"options.protectedHeader",[814,835,836,841,842,845,846,849],{},[187,837,838],{},[199,839,840],{},"unprotected"," — shared, ",[772,843,844],{},"not"," part of AAD. Contains fields from ",[199,847,848],{},"options.sharedUnprotectedHeader"," (metadata that doesn't need cryptographic binding).",[814,851,852,857,858,277,860,277,863,277,866,711,868,870,871,779],{},[187,853,854,855],{},"Per-recipient ",[199,856,702],{}," — unshared, not part of AAD. Contains ",[199,859,407],{},[199,861,862],{},"kid",[199,864,865],{},"epk",[199,867,732],{},[199,869,735],{},", and anything you pass in a recipient's ",[199,872,702],{},[173,874,875,880,881,884,885,779],{},[179,876,879],{"href":877,"rel":878},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc7516#section-7.2.1",[183],"RFC 7516 §7.2.1"," mandates ",[187,882,883],{},"disjointness",": a parameter name cannot appear in more than one tier per recipient. Violations throw ",[199,886,887],{},"ERR_JWE_HEADER_PARAMS_NOT_DISJOINT",[656,889,891],{"id":890},"external-aad","External AAD",[173,893,894,897,898,901,902,905],{},[199,895,896],{},"options.aad"," binds the ciphertext to context that isn't part of the envelope — a document hash, a request URL, a transaction ID. The content cipher's AAD becomes ",[199,899,900],{},"BASE64URL(protected) || '.' || BASE64URL(aad)",", so tampering with ",[772,903,904],{},"either"," side (protected header or external AAD) fails authentication on decrypt.",[446,907,909],{"id":908},"decryptmulti",[199,910,911],{},"decryptMulti",[192,913,916],{"className":454,"code":914,"filename":915,"language":457,"meta":197,"style":197},"import { decryptMulti } from \"unjwt\u002Fjwe\";\n\nconst { payload, recipientIndex, recipientHeader } = await decryptMulti(\n  jweFromWire, \u002F\u002F parsed JSON object — not the stringified form\n  bobEcdhPrivateJwk,\n);\n","decrypt-multi.ts",[199,917,918,931,935,968,976,981],{"__ignoreMap":197},[202,919,920,922,925,927,929],{"class":204,"line":205},[202,921,465],{"class":464},[202,923,924],{"class":208}," { decryptMulti } ",[202,926,471],{"class":464},[202,928,474],{"class":222},[202,930,477],{"class":208},[202,932,933],{"class":204,"line":212},[202,934,483],{"emptyLinePlaceholder":482},[202,936,937,939,942,945,947,950,952,955,958,961,963,966],{"class":204,"line":229},[202,938,488],{"class":464},[202,940,941],{"class":208}," { ",[202,943,944],{"class":215},"payload",[202,946,277],{"class":208},[202,948,949],{"class":215},"recipientIndex",[202,951,277],{"class":208},[202,953,954],{"class":215},"recipientHeader",[202,956,957],{"class":208}," } ",[202,959,960],{"class":464},"=",[202,962,497],{"class":464},[202,964,965],{"class":500}," decryptMulti",[202,967,504],{"class":208},[202,969,970,973],{"class":204,"line":249},[202,971,972],{"class":208},"  jweFromWire, ",[202,974,975],{"class":533},"\u002F\u002F parsed JSON object — not the stringified form\n",[202,977,978],{"class":204,"line":258},[202,979,980],{"class":208},"  bobEcdhPrivateJwk,\n",[202,982,983],{"class":204,"line":301},[202,984,651],{"class":208},[173,986,987,989,990,993],{},[199,988,911],{}," tries each recipient entry until one unwrap succeeds, then decrypts the shared ciphertext with the unwrapped CEK. Compact tokens go through ",[199,991,992],{},"decrypt()","; multi-recipient tokens always come through here.",[656,995,997],{"id":996},"accepted-serializations","Accepted serializations",[173,999,1000,1001,1004,1005,1008],{},"Both ",[187,1002,1003],{},"General"," and ",[187,1006,1007],{},"Flattened"," are accepted — Flattened is auto-normalized to a single-recipient General envelope in memory before processing.",[656,1010,1012],{"id":1011},"key-inputs","Key inputs",[173,1014,1015,1016,1018,1019,1022],{},"Same shape as ",[199,1017,992],{},": a single key, a ",[199,1020,1021],{},"JWKSet",", a lookup function, or a password string.",[656,1024,1026],{"id":1025},"strict-matching","Strict matching",[173,1028,1029,1032,1033,1035,1036,1039,1040,1043],{},[199,1030,1031],{},"strictRecipientMatch: true"," skips any recipient whose header doesn't unambiguously match the provided key (by ",[199,1034,862],{},", or by ",[199,1037,1038],{},"kty","\u002Fcurve\u002Flength). If no recipient matches, throws ",[199,1041,1042],{},"ERR_JWE_NO_MATCHING_RECIPIENT"," — no trial-and-error fallback:",[192,1045,1047],{"className":454,"code":1046,"language":457,"meta":197,"style":197},"await decryptMulti(jwe, bobEcdhPrivateJwk, { strictRecipientMatch: true });\n",[199,1048,1049],{"__ignoreMap":197},[202,1050,1051,1054,1056,1059,1062],{"class":204,"line":205},[202,1052,1053],{"class":464},"await",[202,1055,965],{"class":500},[202,1057,1058],{"class":208},"(jwe, bobEcdhPrivateJwk, { strictRecipientMatch: ",[202,1060,1061],{"class":215},"true",[202,1063,1064],{"class":208}," });\n",[656,1066,1068],{"id":1067},"result-fields","Result fields",[173,1070,1071,1072,1075],{},"Extends the compact ",[199,1073,1074],{},"decrypt"," result with:",[413,1077,1078,1088,1097],{},[416,1079,1080,1083,1084,1087],{},[199,1081,1082],{},"recipientIndex: number"," — which entry of ",[199,1085,1086],{},"recipients"," unwrapped.",[416,1089,1090,1093,1094,1096],{},[199,1091,1092],{},"recipientHeader?"," — the ",[199,1095,702],{}," field from that recipient entry.",[416,1098,1099,1102,1103,1105],{},[199,1100,1101],{},"sharedUnprotectedHeader?"," — the top-level ",[199,1104,840],{}," header, if present.",[446,1107,1109],{"id":1108},"flattened-form","Flattened form",[173,1111,1112,1113,1115],{},"For consumers that strictly expect ",[187,1114,1007],{}," serialization (single recipient, JSON shape):",[192,1117,1120],{"className":454,"code":1118,"filename":1119,"language":457,"meta":197,"style":197},"import { encryptMulti, generalToFlattened } from \"unjwt\u002Fjwe\";\n\nconst general = await encryptMulti(payload, [singleRecipient], opts);\nconst flattened = generalToFlattened(general);\n\u002F\u002F { protected, unprotected?, header?, encrypted_key?, iv, ciphertext, tag, aad? }\n","flattened.ts",[199,1121,1122,1135,1139,1155,1170],{"__ignoreMap":197},[202,1123,1124,1126,1129,1131,1133],{"class":204,"line":205},[202,1125,465],{"class":464},[202,1127,1128],{"class":208}," { encryptMulti, generalToFlattened } ",[202,1130,471],{"class":464},[202,1132,474],{"class":222},[202,1134,477],{"class":208},[202,1136,1137],{"class":204,"line":212},[202,1138,483],{"emptyLinePlaceholder":482},[202,1140,1141,1143,1146,1148,1150,1152],{"class":204,"line":229},[202,1142,488],{"class":464},[202,1144,1145],{"class":215}," general",[202,1147,494],{"class":464},[202,1149,497],{"class":464},[202,1151,501],{"class":500},[202,1153,1154],{"class":208},"(payload, [singleRecipient], opts);\n",[202,1156,1157,1159,1162,1164,1167],{"class":204,"line":249},[202,1158,488],{"class":464},[202,1160,1161],{"class":215}," flattened",[202,1163,494],{"class":464},[202,1165,1166],{"class":500}," generalToFlattened",[202,1168,1169],{"class":208},"(general);\n",[202,1171,1172],{"class":204,"line":258},[202,1173,1174],{"class":533},"\u002F\u002F { protected, unprotected?, header?, encrypted_key?, iv, ciphertext, tag, aad? }\n",[173,1176,1177,1178,1181],{},"Throws ",[199,1179,1180],{},"ERR_JWE_INVALID_SERIALIZATION"," if the input has zero or multiple recipients — Flattened is strictly single-recipient.",[446,1183,1185],{"id":1184},"use-cases","Use cases",[413,1187,1188,1194,1200,1210],{},[416,1189,1190,1193],{},[187,1191,1192],{},"Team documents."," One encrypted file, unlocked by any authorized team member's private key.",[416,1195,1196,1199],{},[187,1197,1198],{},"Broadcast messages."," Encrypt once, fan out to N recipients — bandwidth proportional to N wraps, not N ciphertexts.",[416,1201,1202,1205,1206,1209],{},[187,1203,1204],{},"Revocable membership."," Re-encrypt when the recipient set changes — anyone removed from ",[199,1207,1208],{},"recipients[]"," can no longer decrypt future messages.",[416,1211,1212,1215,1216,1218],{},[187,1213,1214],{},"Hybrid public-key delivery."," Some recipients hold RSA keys, others EC — mix freely with different ",[199,1217,407],{}," per recipient.",[446,1220,1222],{"id":1221},"how-jwe-multi-recipient-differs-from-jws-multi-signature","How JWE multi-recipient differs from JWS multi-signature",[173,1224,1225,1226,1229],{},"They look similar but have substantively different shapes — see the matching ",[179,1227,1228],{"href":46},"JWS multi-signature page"," for the other angle. Highlights:",[413,1231,1232,1249,1258,1269,1279],{},[416,1233,1234,1237,1238,1240,1241,277,1243,1245,1246,1248],{},[187,1235,1236],{},"Shared protected header vs. per-signer."," JWE has one shared ",[199,1239,820],{}," header (with ",[199,1242,714],{},[199,1244,826],{},", etc., part of AAD) and per-recipient ",[199,1247,702],{},". JWS has per-signer protected headers; nothing is shared.",[416,1250,1251,1254,1255,1257],{},[187,1252,1253],{},"Three header tiers vs. two."," JWE adds the ",[199,1256,840],{}," (shared, non-authenticated) tier that JWS lacks.",[416,1259,1260,1263,1264,758,1266,1268],{},[187,1261,1262],{},"Shared CEK."," One random CEK is used for content encryption, and each recipient gets their own wrapped copy. This is why ",[199,1265,757],{},[199,1267,761],{}," can't appear in multi.",[416,1270,1271,1274,1275,1278],{},[187,1272,1273],{},"External AAD."," JWE binds to out-of-band context via ",[199,1276,1277],{},"aad",". JWS has no analog — signatures already cover the whole payload.",[416,1280,1281,1284],{},[187,1282,1283],{},"\"First recipient wins\" semantics."," Decryption terminates as soon as one wrap succeeds. JWS signatures can all be checked independently.",[1286,1287,1288],"style",{},"html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}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 .sVAnh, html code.shiki .sVAnh{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#FDAEB7;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--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 .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":197,"searchDepth":212,"depth":212,"links":1290},[1291,1297,1303,1304,1305],{"id":448,"depth":212,"text":451,"children":1292},[1293,1294,1295,1296],{"id":658,"depth":229,"text":659},{"id":751,"depth":229,"text":752},{"id":800,"depth":229,"text":801},{"id":890,"depth":229,"text":891},{"id":908,"depth":212,"text":911,"children":1298},[1299,1300,1301,1302],{"id":996,"depth":229,"text":997},{"id":1011,"depth":229,"text":1012},{"id":1025,"depth":229,"text":1026},{"id":1067,"depth":229,"text":1068},{"id":1108,"depth":212,"text":1109},{"id":1184,"depth":212,"text":1185},{"id":1221,"depth":212,"text":1222},"md",{},{},{"title":68,"description":197},"a0eUee8zSMU7h0fSHsEfTzPD4-4ob9AKyELz4CeyE78",[1312,1313],{"title":64,"path":65,"stem":66,"description":197,"children":-1},{"title":72,"path":73,"stem":74,"description":197,"children":-1},1776888560030]