---
title: "Cryptography and JWT"
description: "Cryptography and JWT form a critical security layer within the Hono framework, providing robust mechanisms for identity verification, data integrity, and secure transport state management. The arch..."
last_updated: "2026-07-02T09:13:46.878362+00:00"
canonical_url: "https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/system-utilities/cryptography-and-jwt"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [src/utils/jwt/jwt.ts](https://github.com/blade47/hono/blob/main/src/utils/jwt/jwt.ts)
- [src/middleware/secure-headers/secure-headers.ts](https://github.com/blade47/hono/blob/main/src/middleware/secure-headers/secure-headers.ts)
- [src/adapter/aws-lambda/handler.ts](https://github.com/blade47/hono/blob/main/src/adapter/aws-lambda/handler.ts)
- [package.json](https://github.com/blade47/hono/blob/main/package.json)
- [src/middleware/jwt/jwt.ts](https://github.com/blade47/hono/blob/main/src/middleware/jwt/jwt.ts)
- [src/middleware/jwk/jwk.ts](https://github.com/blade47/hono/blob/main/src/middleware/jwk/jwk.ts)
- [src/middleware/bearer-auth/index.ts](https://github.com/blade47/hono/blob/main/src/middleware/bearer-auth/index.ts)
- [src/utils/jwt/jws.ts](https://github.com/blade47/hono/blob/main/src/utils/jwt/jws.ts)
- [src/middleware/jwk/keys.test.json](https://github.com/blade47/hono/blob/main/src/middleware/jwk/keys.test.json)
- [src/hono.ts](https://github.com/blade47/hono/blob/main/src/hono.ts)
- [src/context.ts](https://github.com/blade47/hono/blob/main/src/context.ts)
- [src/preset/quick.ts](https://github.com/blade47/hono/blob/main/src/preset/quick.ts)
- [src/middleware/csrf/index.ts](https://github.com/blade47/hono/blob/main/src/middleware/csrf/index.ts)
- [src/hono-base.ts](https://github.com/blade47/hono/blob/main/src/hono-base.ts)
- [src/adapter/lambda-edge/handler.ts](https://github.com/blade47/hono/blob/main/src/adapter/lambda-edge/handler.ts)
- [src/utils/crypto.ts](https://github.com/blade47/hono/blob/main/src/utils/crypto.ts)
- [src/utils/jwt/types.ts](https://github.com/blade47/hono/blob/main/src/utils/jwt/types.ts)
- [src/middleware/basic-auth/index.ts](https://github.com/blade47/hono/blob/main/src/middleware/basic-auth/index.ts)
- [src/utils/jwt/jwa.ts](https://github.com/blade47/hono/blob/main/src/utils/jwt/jwa.ts)
- [src/utils/jwt/index.ts](https://github.com/blade47/hono/blob/main/src/utils/jwt/index.ts)
- [src/middleware/jwt/index.ts](https://github.com/blade47/hono/blob/main/src/middleware/jwt/index.ts)
- [src/jsx/jsx-runtime.ts](https://github.com/blade47/hono/blob/main/src/jsx/jsx-runtime.ts)
- [src/utils/cookie.ts](https://github.com/blade47/hono/blob/main/src/utils/cookie.ts)
- [src/helper/cookie/index.ts](https://github.com/blade47/hono/blob/main/src/helper/cookie/index.ts)
- [src/request.ts](https://github.com/blade47/hono/blob/main/src/request.ts)
</details>

Cryptography and JWT form a critical security layer within the Hono framework, providing robust mechanisms for identity verification, data integrity, and secure transport state management. The architecture decouples cryptographic primitives from high-level authentication middleware, allowing developers to sign, verify, and decode JSON Web Tokens (JWT) while leveraging the underlying Web Crypto API. This approach ensures Hono remains compliant with modern web standards while remaining runtime-agnostic.

The subsystem addresses common security challenges such as algorithm confusion attacks, token expiration, and unauthorized access. By providing dedicated middleware like `jwt()` and `jwk()`, Hono simplifies the implementation of stateless authentication. These components maintain a clean separation between the cryptographic operations—handled in `jws.ts`—and the routing/request handling logic, ensuring that sensitive token validation logic remains centralized and testable.

Integration with adjacent components is seamless, particularly regarding request context and headers. The `secure-headers` middleware works in tandem with these security modules to prevent vulnerabilities like CSRF or content-injection, while the `cookie` helpers offer cryptographically signed cookies to extend the lifecycle of authentication states. By prioritizing standard-compliant implementations of RFC 7515 (JWS) and RFC 7519 (JWT), this component ensures secure interoperability with external identity providers and authentication services.

## Core Cryptographic Primitives

The core cryptographic operations are abstracted through `jws.ts`, which leverages `crypto.subtle` to perform signing and verification. Rather than implementing proprietary crypto, Hono maps high-level algorithms (like `HS256`, `RS256`, or `ES256`) to the corresponding `SubtleCrypto` parameters. The `getKeyAlgorithm` function acts as a central registry for this mapping, converting a `SignatureAlgorithm` string into the required `KeyAlgorithm` structure.

```mermaid
flowchart TD
    A["User request"] --> B["jwt() middleware"]
    B --> C["Jwt.verify()"]
    C --> D["jws.ts: verifying()"]
    D --> E["jws.ts: importPublicKey()"]
    E --> F["crypto.subtle.verify()"]
```

Sources: [src/utils/jwt/jws.ts:29-48](https://github.com/blade47/hono/blob/main/src/utils/jwt/jws.ts#L29-L48), [src/utils/jwt/jws.ts:122-224](https://github.com/blade47/hono/blob/main/src/utils/jwt/jws.ts#L122-L224)

## JWT Lifecycle and Validation

The `Jwt.verify` function serves as the primary engine for token authentication. It performs a multi-stage validation process: token structure verification, header integrity, expiration/time-based checks, and final signature validation.

> [!IMPORTANT]
> The `verify` function strictly enforces that `alg` (algorithm) is provided. This prevents "None" algorithm attacks where an attacker replaces the algorithm header to bypass signature checks.

The flow ensures that security invariants are maintained before the signature is ever checked:

1. **Split**: Split the token by `.`. Expect exactly 3 parts.
2. **Decode**: Decode header and payload.
3. **Guard**: Validate existence and correctness of `alg` in header.
4. **Time Checks**: Evaluate `nbf` (Not Before), `exp` (Expiration), and `iat` (Issued At) against current server time.
5. **Verify**: Use `verifying()` to compare the signature of the `header.payload` string against the provided public key.

Sources: [src/utils/jwt/jwt.ts:96-188](https://github.com/blade47/hono/blob/main/src/utils/jwt/jwt.ts#L96-L188)

## JWK Verification and Security Invariants

The `verifyWithJwks` function provides a more advanced security model by fetching public keys from a URI or using a provided key set. It specifically hardens the system against Algorithm Confusion Attacks.

> [!WARNING]
> The system explicitly rejects symmetric algorithms (HS256, HS384, HS512) during JWK verification. This prevents an attacker from supplying an asymmetric public key as a symmetric "secret" to force the server into using a weak signature validation logic.

| Design Choice | Benefit | Cost |
| :--- | :--- | :--- |
| Symmetric algorithm rejection | Prevents key confusion attacks | Slightly higher complexity in key management |
| Explicit algorithm validation | Ensures strict cryptographic standards | Requires manual configuration of allowed algorithms |
| `kid` requirement | Enables key rotation | Requires metadata management in token headers |

Sources: [src/utils/jwt/jwt.ts:197-262](https://github.com/blade47/hono/blob/main/src/utils/jwt/jwt.ts#L197-L262)

## Authentication Middleware Surface

The `jwt` and `jwk` middleware wrap the core utilities to provide standard Hono middleware integration. They extract tokens from either the `Authorization` header (default: `Bearer`) or from cookie-based storage.

```ts
// Example: Basic JWT implementation
import { Hono } from 'hono'
import { jwt } from 'hono/jwt'

const app = new Hono()

app.use(
  '/auth/*',
  jwt({
    secret: 'super-secret-key',
    alg: 'HS256',
  })
)

app.get('/auth/page', (c) => {
  const payload = c.get('jwtPayload')
  return c.text(`Authorized, user: ${payload.sub}`)
})
```

The middleware provides an `unauthorizedResponse` helper that standardizes the `WWW-Authenticate` header, ensuring clients receive specific `error` and `error_description` fields when verification fails.

Sources: [src/middleware/jwt/jwt.ts:53-158](https://github.com/blade47/hono/blob/main/src/middleware/jwt/jwt.ts#L53-L158), [src/middleware/jwk/jwk.ts:48-168](https://github.com/blade47/hono/blob/main/src/middleware/jwk/jwk.ts#L48-L168)

## Cookie Signing and Integrity

Hono provides mechanisms for managing signed cookies to preserve authentication state securely. The `serializeSigned` and `parseSigned` utilities use HMAC-SHA256 signatures to ensure cookie values cannot be tampered with by the client.

```mermaid
sequenceDiagram
    participant App
    participant CookieUtils
    participant CryptoSubtle

    App->>CookieUtils: serializeSigned(key, val, secret)
    CookieUtils->>CryptoSubtle: crypto.subtle.sign(HMAC, val)
    CryptoSubtle-->>CookieUtils: signature
    CookieUtils-->>App: Set-Cookie: key=val.signature
```

The `verifySignature` utility uses `crypto.subtle.verify` to check the HMAC, ensuring the integrity of the cookie data before it is made available to the application.

Sources: [src/utils/cookie.ts:39-66](https://github.com/blade47/hono/blob/main/src/utils/cookie.ts#L39-L66), [src/utils/cookie.ts:140-165](https://github.com/blade47/hono/blob/main/src/utils/cookie.ts#L140-L165)

## CSRF Protection Mechanism

The `csrf` middleware complements JWT/Cookie-based auth by validating the origin of requests. It verifies that the request origin and/or `Sec-Fetch-Site` header correspond to a trusted value.

> [!TIP]
> Always use a combination of secure cookies (via `serializeSigned`) and `csrf()` middleware to create a layered defense-in-depth strategy for stateful web apps.

The logic follows a short-circuit evaluation:
1. Identify if the request method is "unsafe" (anything other than `GET` or `HEAD`).
2. Verify the `Content-Type` indicates it could have been triggered by a standard HTML form element.
3. Validate origin via an internal `isAllowedOrigin` handler or `Sec-Fetch-Site`. If both checks fail, the system returns a `403 Forbidden`.

Sources: [src/middleware/csrf/index.ts:94-151](https://github.com/blade47/hono/blob/main/src/middleware/csrf/index.ts#L94-L151)

## Related

- [Authentication Middleware](https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/technical/middleware-ecosystem/authentication-middleware)


## Sitemap

See the full [sitemap](https://www.doc0.app/docs/552ca36e-f67e-41c3-a07a-def9bd9551b0/llms.txt) for all pages in this wiki.
