Crypto è un’implementazione interna avanzata. Non è necessario per le operazioni comuni come post, recupero feed o notifiche. Consultalo quando devi costruire verifica firma di basso livello o implementazioni OAuth per AT Protocol.
Panoramica della crittografia in AT Protocol
AT Protocol adotta la crittografia a curva ellittica (ECC) in modo esteso per realizzare una rete sociale decentralizzata. Gli usi principali sono i seguenti.
| Curva | Algoritmo | Uso principale |
|---|
| secp256r1 (P-256) | ES256 | OAuth (DPoP, Client Assertion) |
| secp256k1 (K256) | ES256K | Verifica firma di Feed Generator e Labeler |
Classi delle coppie di chiavi
AbstractKeypair
AbstractKeypair è la classe base comune per P256 / K256. Internamente utilizza phpseclib3.
// Genera una nuova coppia di chiavi
$keypair = P256::create();
$keypair = K256::create();
// Carica da una chiave privata codificata in Base64 URL-safe
$keypair = P256::load($base64PrivateKey);
// Ottieni in formato PEM
$privatePem = $keypair->privatePEM();
$publicPem = $keypair->publicPEM();
// Converti in JWK (JSON Web Key)
$jwk = $keypair->toJWK();
P256 (secp256r1)
use Revolution\Bluesky\Crypto\P256;
$keypair = P256::create();
Utilizzata in OAuth (DPoP / Client Assertion). OAuthKey estende P256 e carica la chiave privata da config('bluesky.oauth.private_key').
È disponibile anche un comando Artisan per generare una nuova chiave privata OAuth.
php artisan bluesky:new-private-key
K256 (secp256k1)
use Revolution\Bluesky\Crypto\K256;
$keypair = K256::create();
Utilizzata per l’autenticazione di Feed Generator e Labeler. PDS / Relay di Bluesky verificano la firma su questa curva.
DidKey
La classe DidKey codifica e decodifica una chiave pubblica nel formato did:key.
In AT Protocol una chiave pubblica è rappresentata come stringa did:key:z.... È l’aggiunta di un identificatore di curva alla chiave pubblica, seguita da una codifica multibase in Base58btc.
Codifica di una chiave pubblica in did:key
use Revolution\Bluesky\Crypto\DidKey;
use Revolution\Bluesky\Crypto\K256;
$keypair = K256::create();
$publicPem = $keypair->publicPEM();
// Converti nel formato did:key
$didKey = DidKey::format($publicPem);
// => "did:key:zQ3s..."
Parsing della chiave pubblica dal 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 un oggetto chiave pubblica di phpseclib3 dal publicKey (multibase) del DID Document
$publicKey = DidKey::parse($didDoc->publicKey());
JsonWebToken (JWT)
La classe JsonWebToken fornisce codifica e decodifica di JWT.
use Revolution\Bluesky\Crypto\JsonWebToken;
// Genera un JWT (firmato con la chiave privata PEM)
$token = JsonWebToken::encode(
payload: ['iss' => 'did:plc:***', 'aud' => 'https://bsky.social', 'exp' => time() + 60],
key: $privatePem,
alg: 'ES256',
);
// Decodifica il JWT (senza verifica della firma)
$payload = JsonWebToken::decode($token);
DPoP (Demonstrated Proof of Possession)
DPoP è un meccanismo di sicurezza che lega un access token OAuth a una specifica coppia di chiavi del client. Previene gli attacchi di replay del token.
La classe DPoP è utilizzata internamente e normalmente non serve invocarla direttamente. Il middleware OAuthAgent applica automaticamente gli header DPoP.
// Generazione della proof DPoP (per richiesta di token OAuth)
$proof = DPoP::authProof(
jwk: $jsonWebKey,
url: 'https://bsky.social/oauth/token',
method: 'POST',
nonce: $nonce,
);
// Generazione della proof DPoP (per richiesta API, include ath)
$proof = DPoP::apiProof(
jwk: $jsonWebKey,
url: 'https://api.bsky.app/xrpc/...',
method: 'GET',
token: $accessToken,
nonce: $nonce,
);
AT Protocol utilizza il formato di firma compatto a 64 byte, mentre phpseclib3 restituisce firme in formato ASN.1 DER. La classe Signature gestisce questa conversione.
use Revolution\Bluesky\Crypto\Signature;
// ASN.1 DER → compatto (64 byte)
$compact = Signature::toCompact($derSignature);
// Compatto → ASN.1 DER
$der = Signature::fromCompact($compactSignature);
JsonWebKey
JsonWebKey è la classe che rappresenta una JWK (JSON Web Key). Viene usata nella generazione delle proof DPoP.
use Revolution\Bluesky\Crypto\JsonWebKey;
// Genera una JWK da una coppia di chiavi
$jwk = $keypair->toJWK();
// Oppure istanzia direttamente
$jwk = JsonWebKey::load(['kty' => 'EC', 'crv' => 'P-256', ...]);
OAuthKey
OAuthKey è una classe di chiave dedicata a OAuth che estende P256 e usa il valore di config('bluesky.oauth.private_key') come chiave privata.
use Revolution\Bluesky\Crypto\OAuthKey;
// Carica la chiave privata dalla configurazione
$oauthKey = OAuthKey::load();
// Utilizzata per firmare il JWT di Client Assertion
$jwk = $oauthKey->toJWK();
Normalmente viene gestita automaticamente all’interno di Bluesky Socialite.
Link di riferimento