Anleitungen · Teil 4 von 6
Einen versiegelten PoE erstellen
Ein einfacher PoE belegt, dass ein bestimmter Inhalt existiert hat. Ein versiegelter PoE belegt dasselbe, hält den Inhalt selbst aber geheim: Sie verschlüsseln die Bytes für einen oder mehrere Empfängerschlüssel, speichern nur den Chiffretext und verankern den Datensatz on-chain (in der Blockchain). Jede und jeder kann sehen, dass der Datensatz existiert, und seine Struktur verifizieren; entschlüsseln können die Nutzdaten aber nur diejenigen, die einen passenden privaten Schlüssel besitzen. Das Umschlagformat beschreibt Versiegelter PoE, das Bedrohungsmodell Versiegelt bis zur Abholung.
Empfänger adressieren
Ein Empfänger wird über eine Zeichenkette im age-Stil identifiziert. Es gibt zwei
Arten, die sich am Präfix unterscheiden lassen:
age1…: ein klassischer X25519-Schlüssel (32 Byte).age1pqc…: ein hybrider X-Wing-Schlüssel (ML-KEM-768 + X25519, 1216 Byte).
X-Wing (mlkem768x25519) ist der Standard-KEM. Er bleibt auch gegenüber einem
künftigen Quantenangreifer sicher, und jede Identität verfügt stets über eine
age1pqc…-Adresse.
Ein Empfänger teilt Ihnen seine Zeichenkette über einen separaten,
vertrauenswürdigen Kanal mit. Mit parseAgeRecipient wandeln Sie sie zurück in den
rohen öffentlichen Schlüssel, den die Versiegelungs-Hilfsfunktion benötigt:
import { parseAgeRecipient } from '@cardanowall/sdk-ts';
const them = parseAgeRecipient('age1pqc…'); // { kem: 'mlkem768x25519', publicKey: Uint8Array }Wenn Sie selbst einen 32-Byte-Seed besitzen, liefert Ihnen recipientsFromSeed
beide eigenen Adressen. Geben Sie eine davon weiter, damit andere an Sie versiegeln
können, und nehmen Sie Ihren eigenen Schlüssel in die Empfängerliste auf, um den
Lesezugriff auf das von Ihnen Versendete zu behalten:
import { recipientsFromSeed } from '@cardanowall/sdk-ts';
const me = recipientsFromSeed(mySeed); // { age: 'age1…', age1pqc: 'age1pqc…' }Versiegeln und veröffentlichen
Das Versiegeln läuft über ein Gateway, das die Cardano-Transaktion erstellt und verteilt und den Chiffretext für Sie speichert. Richten Sie den Client auf das von Ihnen genutzte Gateway; das SDK ist gateway-unabhängig.
publishSealed erwartet rohe öffentliche Empfängerschlüssel, entnehmen Sie also
publicKey aus jeder geparsten Adresse. Alle Empfänger müssen denselben KEM
verwenden, halten Sie age1pqc…-Schlüssel daher beieinander. Schreiben Sie zuerst
mit quote einen Preis fest, dann veröffentlichen Sie:
import { Label309Client, parseAgeRecipient } from '@cardanowall/sdk-ts';
const client = new Label309Client({
baseUrl: 'https://your-gateway.example',
apiKey: process.env.CW_API_KEY,
});
const content = new TextEncoder().encode('the secret payload');
const recipients = ['age1pqc…recipient', me.age1pqc].map((r) => parseAgeRecipient(r).publicKey);
const quote = await client.poe.quote({
recordBytes: 512,
recipientCount: recipients.length,
fileBytesTotal: content.length,
});
const result = await client.poe.publishSealed({
content,
recipients,
quoteId: quote.quote_id,
// kem defaults to 'mlkem768x25519' (X-Wing); pass 'x25519' only for age1… keys.
});
console.log(result.tx_hash);Die Hilfsfunktion verschlüsselt den Inhalt, lädt den Chiffretext hoch, bindet dessen
ar://-URI und den Klartext-Hash in einen Label-309-Datensatz ein und reicht ihn
ein. Ihr Seed und der Klartext verlassen Ihren Rechner dabei niemals im Klartext.
Mit Python
cardanowall-sdk ist ein byteidentischer Zwilling: derselbe KEM-Standard, derselbe
Umschlag.
import asyncio
import os
from cardanowall import Label309Client, parse_age_recipient
async def main():
content = b"the secret payload"
recipients = [parse_age_recipient("age1pqc…recipient").public_key]
async with Label309Client(
base_url="https://your-gateway.example",
api_key=os.environ["CW_API_KEY"],
) as client:
quote = await client.poe.quote(
record_bytes=512, recipient_count=len(recipients), file_bytes_total=len(content)
)
result = await client.poe.publish_sealed(
content=content, recipients=recipients, quote_id=quote["quote_id"]
)
print(result["tx_hash"])
asyncio.run(main())Mit Rust
Das cardanowall-Crate versiegelt über denselben Gateway-Client.
parse_age_recipient dekodiert jede Adresse in den rohen Schlüssel, und kem: None
behält den X-Wing-Standard bei:
use cardanowall::client::{
Label309Client, Label309ClientConfig, PublishSealedInput, QuoteInput,
};
use cardanowall::recipient::parse_age_recipient;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = Label309Client::new(Label309ClientConfig {
base_url: Some("https://your-gateway.example".into()),
api_key: std::env::var("CW_API_KEY").ok(),
})?;
let content = b"the secret payload".to_vec();
let recipients = vec![parse_age_recipient("age1pqc…recipient")?.public_key];
let quote = client.poe().quote(&QuoteInput {
record_bytes: 512,
recipient_count: recipients.len() as u64,
file_bytes_total: content.len() as u64,
})?;
let result = client.poe().publish_sealed(&PublishSealedInput {
content,
recipients,
quote_id: quote.quote_id,
hash_alg: None,
kem: None, // defaults to mlkem768x25519 (X-Wing); set Some for x25519
signer: None,
idempotency_key: None,
})?;
println!("{:?}", result.tx_hash);
Ok(())
}Das CLI veröffentlicht reine Hash-Datensätze und Merkle-Datensätze; das Versiegeln ist derzeit ein reiner SDK-Ablauf.
Sobald der Datensatz endgültig in die Blockchain aufgenommen ist, findet ihn jeder Empfänger, entschlüsselt die Nutzdaten mit seinem privaten Schlüssel und berechnet den Klartext-Hash neu, um den Kreis zu schließen. Das ist die Empfänger-Seite von Einen Datensatz verifizieren.
Versiegeln Sie auch an sich selbst
publishSealed fügt Sie nicht stillschweigend zur Empfängerliste hinzu. Nehmen Sie keinen Ihrer
eigenen Schlüssel auf, veröffentlichen Sie einen Datensatz, den Sie nie wieder lesen können.
Nehmen Sie me.age1pqc (oder me.age) unter die Empfänger auf, wann immer Sie den Zugriff auf
das von Ihnen Versendete behalten möchten.