> ## 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 – Kryptografie im AT Protocol

> Das Crypto-Modul des Laravel-Bluesky-Pakets. Erläutert Schlüsselpaare für P-256 / secp256k1, DID-Keys, JWT, DPoP und Signatur-Konvertierungen.

<Warning>
  Crypto ist eine tiefgehende interne Implementierung. Für normale Posts, Feed-Abrufe oder Benachrichtigungen wird es nicht benötigt. Ziehen Sie es heran, wenn Sie Low-Level-Signaturprüfungen oder OAuth-Implementierungen für das AT Protocol aufbauen.
</Warning>

## Überblick über die Kryptografie im AT Protocol

Das AT Protocol setzt für ein dezentrales soziales Netzwerk umfassend auf Elliptic-Curve-Cryptography (ECC). Die Hauptanwendungen sind:

```mermaid theme={null}
graph TD
    A["Schlüsselpaar<br>(P-256 / secp256k1)"] --> B["Signieren mit privatem Schlüssel"]
    A --> C["Öffentlichen Schlüssel als did:key codieren"]
    B --> D["DPoP-Token (OAuth)"]
    B --> E["Commit-Signatur (Repository)"]
    B --> F["Label-Signatur (Labeler)"]
    C --> G["Registrierung im DID-Document"]
    G --> H["Signatur mit öffentlichem Schlüssel verifizieren"]
```

| Kurve             | Algorithmus | Hauptanwendung                                 |
| ----------------- | ----------- | ---------------------------------------------- |
| secp256r1 (P-256) | ES256       | OAuth (DPoP, Client Assertion)                 |
| secp256k1 (K256)  | ES256K      | Signaturprüfung für Feed Generator und Labeler |

***

## Schlüsselpaar-Klassen

### AbstractKeypair

`AbstractKeypair` ist die gemeinsame Basisklasse für P256 / K256. Intern wird [phpseclib3](https://phpseclib.com/) verwendet.

```php theme={null}
// Neues Schlüsselpaar generieren
$keypair = P256::create();
$keypair = K256::create();

// Aus URL-safe Base64-encodiertem privatem Schlüssel laden
$keypair = P256::load($base64PrivateKey);

// Als PEM abrufen
$privatePem = $keypair->privatePEM();
$publicPem  = $keypair->publicPEM();

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

### P256 (secp256r1)

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

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

Wird für OAuth (DPoP / Client Assertion) verwendet. `OAuthKey` erbt von P256 und lädt den privaten Schlüssel aus `config('bluesky.oauth.private_key')`.

Es gibt auch ein Artisan-Kommando zum Erzeugen eines neuen OAuth-Privatschlüssels.

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

### K256 (secp256k1)

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

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

Wird für die Authentifizierung von Feed Generator und Labeler verwendet. Bluesky-PDS/-Relay verifizieren Signaturen mit dieser Kurve.

***

## DidKey

Die Klasse `DidKey` codiert und decodiert öffentliche Schlüssel im `did:key`-Format.

### Was ist das did:key-Format?

Im AT Protocol wird ein öffentlicher Schlüssel als String `did:key:z...` dargestellt. Dabei wird der öffentliche Schlüssel um einen Kurven-Identifier ergänzt und multibase-encodiert in Base58btc.

```mermaid theme={null}
graph LR
    A["Öffentlicher Schlüssel (PEM)"] --> B["Kurven-Identifier + komprimierter Public Key"]
    B --> C["Base58btc-Encoding"]
    C --> D["did:key:z..."]
```

### Öffentlichen Schlüssel als did:key codieren

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

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

// In das did:key-Format umwandeln
$didKey = DidKey::format($publicPem);
// => "did:key:zQ3s..."
```

### Öffentlichen Schlüssel aus einem DID-Document parsen

```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()
);

// Aus publicKey (multibase) des DID-Documents ein phpseclib3-Public-Key-Objekt erzeugen
$publicKey = DidKey::parse($didDoc->publicKey());
```

***

## JsonWebToken (JWT)

Die Klasse `JsonWebToken` bietet Encoding/Decoding von JWTs.

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

// JWT erzeugen (Signieren mit privatem PEM-Schlüssel)
$token = JsonWebToken::encode(
    payload: ['iss' => 'did:plc:***', 'aud' => 'https://bsky.social', 'exp' => time() + 60],
    key: $privatePem,
    alg: 'ES256',
);

// JWT decodieren (ohne Signaturprüfung)
$payload = JsonWebToken::decode($token);
```

***

## DPoP (Demonstrated Proof of Possession)

DPoP ist ein Sicherheitsmechanismus, der OAuth-Access-Tokens an ein bestimmtes Client-Schlüsselpaar bindet. Er verhindert Replay-Angriffe mit den Tokens.

```mermaid theme={null}
sequenceDiagram
    participant App as Laravel-Anwendung
    participant AS as Authorization Server
    participant RS as Resource Server

    App->>AS: PAR-Request (+ DPoP-Header)
    AS-->>App: request_uri
    App->>AS: Token-Request (+ DPoP-Header)
    AS-->>App: Access Token (DPoP-bound)
    App->>RS: API-Request (+ DPoP-Header + ath)
    RS-->>App: Response
```

Die Klasse `DPoP` wird intern verwendet und muss normalerweise nicht direkt aufgerufen werden. Die Middleware des `OAuthAgent` fügt den DPoP-Header automatisch hinzu.

```php theme={null}
// DPoP-Proof erzeugen (für OAuth-Token-Request)
$proof = DPoP::authProof(
    jwk: $jsonWebKey,
    url: 'https://bsky.social/oauth/token',
    method: 'POST',
    nonce: $nonce,
);

// DPoP-Proof erzeugen (für API-Requests, mit ath)
$proof = DPoP::apiProof(
    jwk: $jsonWebKey,
    url: 'https://api.bsky.app/xrpc/...',
    method: 'GET',
    token: $accessToken,
    nonce: $nonce,
);
```

***

## Signature (Signaturformat-Konvertierung)

Das AT Protocol verwendet ein kompaktes 64-Byte-Signaturformat, während phpseclib3 ASN.1-DER zurückgibt. Die Klasse `Signature` übernimmt diese Umwandlung.

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

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

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

***

## JsonWebKey

`JsonWebKey` repräsentiert einen JWK (JSON Web Key) und wird zur Erzeugung von DPoP-Proofs verwendet.

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

// JWK aus dem Schlüsselpaar erzeugen
$jwk = $keypair->toJWK();

// Oder direkt instanziieren
$jwk = JsonWebKey::load(['kty' => 'EC', 'crv' => 'P-256', ...]);
```

***

## OAuthKey

`OAuthKey` ist eine OAuth-spezifische Schlüsselklasse, die von P256 erbt. Sie verwendet den Wert von `config('bluesky.oauth.private_key')` als privaten Schlüssel.

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

// Privaten Schlüssel aus der Konfiguration laden
$oauthKey = OAuthKey::load();

// Wird zum Signieren des Client-Assertion-JWT verwendet
$jwk = $oauthKey->toJWK();
```

Dies wird normalerweise intern von Bluesky Socialite verarbeitet.

***

## Weiterführende Links

* [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

- [Core – Kernoperationen des AT Protocols](/de/packages/laravel-bluesky/core.md)
- [Laravel AI SDK](/de/ai-sdk.md)
- [WebSocket (Jetstream / Firehose)](/de/packages/laravel-bluesky/websocket.md)
- [Laravel und KI-Entwicklung](/de/ai.md)
- [BlueskyManager und HasShortHand](/de/packages/laravel-bluesky/bluesky-manager.md)
