Passer au contenu principal
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.

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 :
CourbeAlgorithmeUsage principal
secp256r1 (P-256)ES256OAuth (DPoP, Client Assertion)
secp256k1 (K256)ES256KVé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.
// 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)

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.
php artisan bluesky:new-private-key

K256 (secp256k1)

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.

Encoder une clé publique en did:key

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

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.
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. 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.
// 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.
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.
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').
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

Source : src/Crypto/
Dernière modification le 13 juillet 2026