Saltar al contenido principal
Crypto es una implementación interna avanzada. No es necesaria para las operaciones habituales como publicar, obtener feeds o notificaciones. Consúltala cuando quieras construir verificaciones de firma o implementaciones de OAuth de bajo nivel del AT Protocol.

Descripción general de la criptografía en AT Protocol

Para construir una red social descentralizada, AT Protocol adopta ampliamente la criptografía de curva elíptica (ECC). Sus usos principales son los siguientes.
CurvaAlgoritmoUso principal
secp256r1 (P-256)ES256OAuth (DPoP, Client Assertion)
secp256k1 (K256)ES256KVerificación de firmas de Feed Generator y Labeler

Clases de par de claves

AbstractKeypair

AbstractKeypair es la clase base común para P256 / K256. Internamente utiliza phpseclib3.
// Genera un nuevo par de claves
$keypair = P256::create();
$keypair = K256::create();

// Carga desde una clave privada codificada en Base64 URL-safe
$keypair = P256::load($base64PrivateKey);

// Obtén en formato PEM
$privatePem = $keypair->privatePEM();
$publicPem  = $keypair->publicPEM();

// Convierte a JWK (JSON Web Key)
$jwk = $keypair->toJWK();

P256 (secp256r1)

use Revolution\Bluesky\Crypto\P256;

$keypair = P256::create();
Se usa en OAuth (DPoP / Client Assertion). OAuthKey hereda de P256 y carga la clave privada desde config('bluesky.oauth.private_key'). También existe un comando Artisan para generar una nueva clave privada OAuth.
php artisan bluesky:new-private-key

K256 (secp256k1)

use Revolution\Bluesky\Crypto\K256;

$keypair = K256::create();
Se usa para la autenticación del Feed Generator y el Labeler. El PDS / Relay de Bluesky verifica las firmas con esta curva.

DidKey

La clase DidKey codifica y decodifica claves públicas al formato did:key.

Qué es el formato did:key

En AT Protocol, las claves públicas se representan como una cadena did:key:z.... Consiste en un identificador de curva más la clave pública comprimida, codificados en multibase con Base58btc.

Codificar clave pública a did:key

use Revolution\Bluesky\Crypto\DidKey;
use Revolution\Bluesky\Crypto\K256;

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

// Convierte al formato did:key
$didKey = DidKey::format($publicPem);
// => "did:key:zQ3s..."

Parsear la clave pública desde el 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()
);

// Genera el objeto de clave pública de phpseclib3 desde el publicKey (multibase) del DID Document
$publicKey = DidKey::parse($didDoc->publicKey());

JsonWebToken (JWT)

La clase JsonWebToken proporciona codificación y decodificación de JWT.
use Revolution\Bluesky\Crypto\JsonWebToken;

// Genera un JWT (firmando con clave privada PEM)
$token = JsonWebToken::encode(
    payload: ['iss' => 'did:plc:***', 'aud' => 'https://bsky.social', 'exp' => time() + 60],
    key: $privatePem,
    alg: 'ES256',
);

// Decodifica un JWT (sin verificar la firma)
$payload = JsonWebToken::decode($token);

DPoP (Demonstrated Proof of Possession)

DPoP es un mecanismo de seguridad que vincula el token de acceso OAuth a un par de claves específico del cliente. Previene ataques de replay del token. La clase DPoP se usa internamente y normalmente no necesitas invocarla directamente. El middleware de OAuthAgent añade automáticamente la cabecera DPoP.
// Generación de la prueba DPoP (para la petición de token OAuth)
$proof = DPoP::authProof(
    jwk: $jsonWebKey,
    url: 'https://bsky.social/oauth/token',
    method: 'POST',
    nonce: $nonce,
);

// Generación de la prueba DPoP (para peticiones API, incluye ath)
$proof = DPoP::apiProof(
    jwk: $jsonWebKey,
    url: 'https://api.bsky.app/xrpc/...',
    method: 'GET',
    token: $accessToken,
    nonce: $nonce,
);

Signature (conversión de formatos de firma)

AT Protocol utiliza un formato de firma compacto de 64 bytes, pero phpseclib3 devuelve el formato ASN.1 DER. La clase Signature se encarga de esta conversión.
use Revolution\Bluesky\Crypto\Signature;

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

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

JsonWebKey

JsonWebKey es la clase que representa un JWK (JSON Web Key). Se usa para generar las pruebas DPoP.
use Revolution\Bluesky\Crypto\JsonWebKey;

// Genera un JWK a partir del par de claves
$jwk = $keypair->toJWK();

// O instancia directamente
$jwk = JsonWebKey::load(['kty' => 'EC', 'crv' => 'P-256', ...]);

OAuthKey

OAuthKey es una clase de clave específica de OAuth que hereda de P256 y utiliza el valor de config('bluesky.oauth.private_key') como clave privada.
use Revolution\Bluesky\Crypto\OAuthKey;

// Carga la clave privada desde la configuración
$oauthKey = OAuthKey::load();

// Se usa para firmar el JWT del Client Assertion
$jwk = $oauthKey->toJWK();
Normalmente se gestiona automáticamente dentro de Bluesky Socialite.

Enlaces de referencia

Source: src/Crypto/
Última modificación el 13 de julio de 2026