====== std.crypto.rsa ======
RSA-Signaturen nach **PKCS#1 v1.5 mit SHA-256** — gedacht für das Signieren von JWTs gegenüber Cloud-Diensten (''[[lyx_-_programmiersprache:units:cloud:gcp|std.cloud.gcp]]'' nutzt sie für Google-Service-Account-Schlüssel).
> **Diese Unit ist die einzige Krypto-Unit mit einer externen Abhängigkeit.** Sie bindet ''libcrypto.so.3'' (OpenSSL 3) per FFI ein und bricht damit das ''Zero-External-Dependencies''-Prinzip der übrigen Standardbibliothek. Ohne installiertes OpenSSL 3 lässt sich ein Programm, das sie importiert, nicht ausführen.
>
> Wo es geht, die eigenen Implementierungen vorziehen: ''[[lyx_-_programmiersprache:units:crypto:ecc|std.crypto.ecc]]'' (ECDSA secp256k1), ''[[lyx_-_programmiersprache:units:crypto:x25519|std.crypto.x25519]]'' oder ''[[lyx_-_programmiersprache:units:crypto:pqc:mldsa|std.crypto.pqc.mldsa]]''. RSA ist hier, weil Gegenstellen es verlangen — nicht, weil es die bessere Wahl wäre.
**Autor:** Andreas Röne\\
**Copyright:** 2024-2026 Andreas Röne
→ [[lyx_-_programmiersprache:units:crypto|std.crypto]] · [[lyx_-_programmiersprache:units:cloud:gcp|std.cloud.gcp]] · [[lyx_-_programmiersprache:units|Standard Library]]
----
===== Funktionen =====
^ Signatur ^ Beschreibung ^
| ''RSAKeyLoad(pem: int64, pemLen: int64): int64'' | Privaten Schlüssel aus PEM-Bytes laden. Liefert einen Schlüssel-Handle (''EVP_PKEY*'') oder ''0'' bei Fehler. ''pemLen = -1'' für nullterminierte Eingabe |
| ''RSAKeyBits(key: int64): int64'' | Schlüssellänge in Bit (2048, 4096, …); ''0'' bei ungültigem Handle |
| ''RSASign(key, data, dataLen, sig, sigLenOut): int64'' | Signiert ''dataLen'' Bytes ab ''data''. ''sig'' muss ''RSAKeyBits(key)/8'' Bytes fassen; ''sigLenOut'' zeigt auf ein ''int64'', das die tatsächliche Signaturlänge aufnimmt. Liefert ''1'' bei Erfolg, ''0'' sonst |
| ''RSAKeyFree(key: int64)'' | Schlüssel freigeben |
import std.io;
import std.fs;
import std.crypto.rsa;
fn main(): int64 {
var pem: pchar := alloc(4096) as pchar;
var pemLen: int64 := ReadFile("service-account.pem"c, pem, 4095);
var key: int64 := RSAKeyLoad(pem as int64, pemLen);
if (key == 0) {
PrintLn("Schluessel konnte nicht geladen werden");
return 1;
}
var bits: int64 := RSAKeyBits(key);
var sig: int64 := alloc(bits / 8);
var lenOut: int64 := alloc(8);
var daten: pchar := "der zu signierende Text"c;
if (RSASign(key, daten as int64, 23, sig, lenOut) == 1) {
PrintLn(IntToStr(peek64(lenOut))); // Signaturlaenge in Bytes
}
RSAKeyFree(key);
return 0;
}
----
===== Grenzen =====
* **Nur Signieren, kein Prüfen.** Eine ''RSAVerify''-Gegenstelle gibt es nicht — die Unit ist auf den Client-Fall zugeschnitten, in dem man selbst signiert und die Gegenseite prüft.
* **Nur private Schlüssel.** ''RSAKeyLoad'' liest über ''PEM_read_bio_PrivateKey''; öffentliche Schlüssel und Zertifikate werden nicht geladen.
* **Kein Verschlüsseln/Entschlüsseln**, kein PSS, kein OAEP. Fest verdrahtet ist PKCS#1 v1.5 über SHA-256.
* **Passwortgeschützte PEM-Dateien** werden nicht unterstützt: Der Callback für die Passphrase wird als ''0'' übergeben, ein verschlüsselter Schlüssel liefert also ''0''.
----
Letzte Aktualisierung: 2026-08-11