# Authenticated Requests

To carry out an unauthenticated request, 4 headers are required:

1. Authentication Header - `X-Encrypted-Session or`` ``X-Encrypted-WebAuthn-Signature or`` ``X-Encrypted-Key-Signature`
2. `X-Encrypted-Key`
3. `X-Encrypted-User`&#x20;
4. `X-Scope-Id`&#x20;

`X-Encrypted-Session` is obtained when you authenticate with the [authenticating-with-api](https://docs.0xpass.io/authentication/passkeys/authentication/authenticating-with-api "mention") endpoint. This is used by enclave to verify  your requests. Other 2 types of headers are obtained by signing the user details object directly using your auth method (passkeys or private key)

To setup an `X-Encrypted-Key` you need to generate a random AES Key, and then RSA encrypt it with the secure enclaves public key, we'll use TypeScript for the example below.

Here we setup a `cryptoObj` that can work in both browser and server environments and then a function to generate an AES Key.

```javascript
const cryptoObj = typeof window !== "undefined" ? window.crypto : crypto;

export const generateAesKey = async () => {
  const cryptoKey = await cryptoObj.subtle.generateKey(
    {
      name: "AES-GCM",
      length: 256,
    },
    true,
    ["encrypt", "decrypt"]
  );
  return await cryptoObj.subtle.exportKey("raw", cryptoKey);
};
```

Next we setup two function an `encrypt` function, which we then use in our `rsaEncrypt` function.

```typescript
const encrypt = async (algo, key, data) => {
  try {
    const encryptedResult = await cryptoObj.subtle.encrypt(algo, key, data);
    return encryptedResult;
  } catch (error) {
    console.error("Encryption error:", error);
    throw error;
  }
};

const rsaEncrypt = async (
  plainText: string,
  encryptionKey: BufferSource,
  keyFormat: "spki" = "spki",
  hashName: "SHA-256" = "SHA-256"
) => {
  if (!encryptionKey) {
    throw Error("Encryption key not initialized");
  }

  const encoder = new TextEncoder();
  const data = encoder.encode(plainText);

  let cryptoKey: CryptoKey;
  let encrypted: ArrayBuffer;

  try {
    cryptoKey = await importKey(
      keyFormat,
      encryptionKey,
      { name: "RSA-OAEP", hash: { name: hashName } },
      ["encrypt"]
    );
    encrypted = await encrypt({ name: "RSA-OAEP" }, cryptoKey, data);
    return btoa(String.fromCharCode.apply(null, new Uint8Array(encrypted)));
  } catch (error) {
    console.error("RSA-OAEP Encryption error:", error);
    throw error;
  }
};


export const aesEncrypt = async (
  plainText: string,
  encryptionKey: BufferSource,
  keyFormat: "raw" = "raw",
  keyLength: number = 256
) => {
  if (!encryptionKey) {
    throw Error("Encryption key not initialized");
  }

  const encoder = new TextEncoder();
  const data = encoder.encode(plainText);
  let cryptoKey: CryptoKey;
  let encrypted: ArrayBuffer;

  try {
    cryptoKey = await importKey(keyFormat, encryptionKey, { name: "AES-GCM", length: keyLength }, [
      "encrypt",
    ]);

    const iv = cryptoObj.getRandomValues(new Uint8Array(12)); // Initialization vector

    encrypted = await encrypt({ name: "AES-GCM", iv }, cryptoKey, data);

    const combined = new Uint8Array(iv.length + encrypted.byteLength);
    combined.set(iv, 0);
    combined.set(new Uint8Array(encrypted), iv.length);

    return btoa(String.fromCharCode.apply(null, combined));
  } catch (error) {
    console.error("AES-GCM Encryption error:", error);
    throw error;
  }
};

```

&#x20;With these function setup, we are able to generate our AES key, and then RSA Encrypt it using the public key of the secure enclave.&#x20;

```typescript
const enclavePublicKey = 
  "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvQOa1gkatuN6KjaS4KEWsVZAN9i4Cf0j9jlmBW5RwCJ3Bxo32McP7axt4Ev6sMWM24lpCgXgu68S9KBYRcrcEB6dRcaupFGd+ER7M518fiJ0VtCZ+XRnmwn9fqEvotp9DPZOysJkUQ60kugCRKwNvfZzAFcDiubwiqsUY2sCm943a/u9Hym51SEetG+ZFPJZFOBqwRSGkOgGZ+9Ac7ITE+bWLCZk9DlzRu+BIoDOFzXZIn+/0a0X8BnLtRY4g50aew4J+4OllQagBbhYnPMvYExYIEUx6bdjQicw0Js6s2pHr+SFAX23kQtbVOVxb5+KEGp1d+6Q4Gx7FBoyWI5qPQIDAQAB";

const aesKey = await generateAesKey();
const aesKeyBytes = new Uint8Array(aesKey);
const aesKeyString = btoa(String.fromCharCode(...aesKeyBytes));
const encryptedAesKey = await rsaEncrypt(aesKeyString, enclavePublicKey);
const userDetails = {
    username: "john_doe",
    userDisplayName: "john_doe_crypto",
};
const encryptedUser = await aesEncrypt(JSON.stringify(userDetails), aesKey);
```

Now you have your `encryptedAesKey` and `encryptedUser` you can use this value as the value in the request header as `X-Encrypted-Key` . With `X-Scope-Id, X-Encrypted-User` , X-Encrypted-Session and `X-Encrypted-Key` setup, you can now start interacting with Passport API to sign messages, transactions and everythig else!
