> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Crypto — chiffrement AT Protocol

> Module Crypto du package Laravel Bluesky. Paires de clés P-256 / secp256k1, clés DID, JWT, DPoP et conversion de signatures.

<Warning>
  Crypto est une implémentation interne avancée. Il n'est pas requis pour les opérations habituelles (publication, récupération de flux, notifications, etc.). Consultez cette page si vous construisez une vérification de signature bas niveau ou une implémentation OAuth pour AT Protocol.
</Warning>

## Aperçu du chiffrement dans AT Protocol

AT Protocol s'appuie largement sur la cryptographie sur courbes elliptiques (ECC) pour bâtir un réseau social décentralisé. Ses usages principaux sont les suivants :

```mermaid theme={null}
graph TD
    A["Paire de clés<br>(P-256 / secp256k1)"] --> B["Signature avec la clé privée"]
    A --> C["Encodage de la clé publique en did:key"]
    B --> D["Token DPoP (OAuth)"]
    B --> E["Signature de commit (dépôt)"]
    B --> F["Signature de label (Labeler)"]
    C --> G["Inscription dans le DID Document"]
    G --> H["Vérification de signature avec la clé publique"]
```

| Courbe            | Algorithme | Usage principal                                             |
| ----------------- | ---------- | ----------------------------------------------------------- |
| secp256r1 (P-256) | ES256      | OAuth (DPoP, Client Assertion)                              |
| secp256k1 (K256)  | ES256K     | Vérification des signatures des Feed Generators et Labelers |

***

## Classes de paires de clés

### AbstractKeypair

`AbstractKeypair` est la classe de base commune à P256 et K256. En interne, elle utilise [phpseclib3](https://phpseclib.com/).

```php theme={null}
// Générer une nouvelle paire de clés
$keypair = P256::create();
$keypair = K256::create();

// Charger une clé privée encodée en Base64 URL-safe
$keypair = P256::load($base64PrivateKey);

// Récupérer au format PEM
$privatePem = $keypair->privatePEM();
$publicPem  = $keypair->publicPEM();

// Convertir en JWK (JSON Web Key)
$jwk = $keypair->toJWK();
```

### P256 (secp256r1)

```php theme={null}
use Revolution\Bluesky\Crypto\P256;

$keypair = P256::create();
```

Utilisée pour OAuth (DPoP / Client Assertion). `OAuthKey` étend P256 et charge la clé privée depuis `config('bluesky.oauth.private_key')`.

Une commande Artisan est également fournie pour générer une nouvelle clé privée OAuth.

```bash theme={null}
php artisan bluesky:new-private-key
```

### K256 (secp256k1)

```php theme={null}
use Revolution\Bluesky\Crypto\K256;

$keypair = K256::create();
```

Utilisée pour l'authentification des Feed Generators et Labelers. Le PDS / Relay de Bluesky vérifie les signatures sur cette courbe.

***

## DidKey

La classe `DidKey` encode et décode les clés publiques au format `did:key`.

### Qu'est-ce que le format did:key ?

Dans AT Protocol, une clé publique est représentée par la chaîne `did:key:z...`. C'est une clé publique préfixée par un identifiant de courbe, encodée en multibase Base58btc.

```mermaid theme={null}
graph LR
    A["Clé publique (PEM)"] --> B["Identifiant de courbe + clé publique compressée"]
    B --> C["Encodage Base58btc"]
    C --> D["did:key:z..."]
```

### Encoder une clé publique en did:key

```php theme={null}
use Revolution\Bluesky\Crypto\DidKey;
use Revolution\Bluesky\Crypto\K256;

$keypair = K256::create();
$publicPem = $keypair->publicPEM();

// Conversion au format did:key
$didKey = DidKey::format($publicPem);
// => "did:key:zQ3s..."
```

### Analyser la clé publique depuis un DID Document

```php theme={null}
use Revolution\Bluesky\Crypto\DidKey;
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Support\DidDocument;

$didDoc = DidDocument::make(
    Bluesky::identity()->resolveDID('did:plc:***')->json()
);

// Crée un objet clé publique phpseclib3 à partir de publicKey (multibase) du DID Document
$publicKey = DidKey::parse($didDoc->publicKey());
```

***

## JsonWebToken (JWT)

La classe `JsonWebToken` fournit l'encodage et le décodage de JWT.

```php theme={null}
use Revolution\Bluesky\Crypto\JsonWebToken;

// Générer un JWT (signé avec la clé privée au format PEM)
$token = JsonWebToken::encode(
    payload: ['iss' => 'did:plc:***', 'aud' => 'https://bsky.social', 'exp' => time() + 60],
    key: $privatePem,
    alg: 'ES256',
);

// Décoder un JWT (sans vérification de signature)
$payload = JsonWebToken::decode($token);
```

***

## DPoP (Demonstrated Proof of Possession)

DPoP est un mécanisme de sécurité qui lie un access token OAuth à une paire de clés client donnée. Il prévient les attaques par rejeu.

```mermaid theme={null}
sequenceDiagram
    participant App as Application Laravel
    participant AS as Serveur d'autorisation
    participant RS as Serveur de ressources

    App->>AS: Requête PAR (+ header DPoP)
    AS-->>App: request_uri
    App->>AS: Requête de token (+ header DPoP)
    AS-->>App: Access token (lié via DPoP)
    App->>RS: Requête API (+ header DPoP + ath)
    RS-->>App: Réponse
```

La classe `DPoP` est utilisée en interne et n'a normalement pas besoin d'être appelée directement. Le middleware `OAuthAgent` ajoute automatiquement les en-têtes DPoP.

```php theme={null}
// Génération d'une preuve DPoP (pour une requête de token OAuth)
$proof = DPoP::authProof(
    jwk: $jsonWebKey,
    url: 'https://bsky.social/oauth/token',
    method: 'POST',
    nonce: $nonce,
);

// Génération d'une preuve DPoP (pour une requête API, avec ath)
$proof = DPoP::apiProof(
    jwk: $jsonWebKey,
    url: 'https://api.bsky.app/xrpc/...',
    method: 'GET',
    token: $accessToken,
    nonce: $nonce,
);
```

***

## Signature (conversion de format)

AT Protocol utilise un format compact de signature de 64 octets, alors que phpseclib3 renvoie un format ASN.1 DER. La classe `Signature` assure cette conversion.

```php theme={null}
use Revolution\Bluesky\Crypto\Signature;

// ASN.1 DER → compact (64 octets)
$compact = Signature::toCompact($derSignature);

// Compact → ASN.1 DER
$der = Signature::fromCompact($compactSignature);
```

***

## JsonWebKey

`JsonWebKey` représente un JWK (JSON Web Key). Il est utilisé pour générer les preuves DPoP.

```php theme={null}
use Revolution\Bluesky\Crypto\JsonWebKey;

// Générer un JWK depuis une paire de clés
$jwk = $keypair->toJWK();

// Ou instancier directement
$jwk = JsonWebKey::load(['kty' => 'EC', 'crv' => 'P-256', ...]);
```

***

## OAuthKey

`OAuthKey` est une classe de clé spécifique à OAuth qui étend P256 et utilise comme clé privée la valeur de `config('bluesky.oauth.private_key')`.

```php theme={null}
use Revolution\Bluesky\Crypto\OAuthKey;

// Charger la clé privée depuis la configuration
$oauthKey = OAuthKey::load();

// Utilisée pour signer le JWT Client Assertion
$jwk = $oauthKey->toJWK();
```

En temps normal, ceci est géré automatiquement par Bluesky Socialite en interne.

***

## Liens utiles

* [AT Protocol: Identity](https://atproto.com/guides/identity)
* [AT Protocol: Cryptography spec](https://atproto.com/specs/cryptography)
* [phpseclib3](https://phpseclib.com/)

<Info>
  Source : [src/Crypto/](https://github.com/invokable/laravel-bluesky/tree/main/src/Crypto)
</Info>


## Related topics

- [Chiffrement (Encryption)](/fr/encryption.md)
- [Authentification OAuth 2.0 - Google Sheets API for Laravel](/fr/packages/laravel-google-sheets/oauth.md)
- [Configuration](/fr/configuration.md)
- [Routage](/fr/routing.md)
- [Core — opérations AT Protocol de base](/fr/packages/laravel-bluesky/core.md)
