Start · Sprachen · JavaScript · Referenz · AesCtrParams

AesCtrParams

Schnittstelle

Parameter-Objekt für den Algorithmus AES-CTR. Wird an <code>SubtleCrypto.encrypt()</code>, <code>decrypt()</code>, <code>wrapKey()</code> und <code>unwrapKey()</code> übergeben.

seit JavaScript Baseline: alle modernen Browser (Web Crypto API), Kategorie: webapi

Signatur

interface AesCtrParams extends Algorithm { name: "AES-CTR"; counter: BufferSource; length: number }

Beschreibung

AesCtrParams ist ein Wörterbuch (Dictionary) der Web Crypto API, also kein Konstruktor und keine Klasse. Man übergibt ein einfaches Objektliteral als algorithm-Argument an crypto.subtle.encrypt(), decrypt(), wrapKey() oder unwrapKey(), wenn ein AES-Schlüssel im Counter-Modus (CTR) verwendet werden soll.

Im CTR-Modus wird ein 16 Byte großer Zählerblock verschlüsselt. Das Ergebnis wird per XOR mit dem Klartext verknüpft. Der Zählerblock besteht aus zwei Teilen: einer Nonce (einmalig pro Nachricht) in den oberen Bits und dem eigentlichen Zähler in den unteren length Bits. Der Zähler wird für jeden Block um eins erhöht. So wird AES zu einer Stromchiffre: Es ist kein Padding nötig, und Geheimtext und Klartext sind gleich lang.

AES-CTR eignet sich, wenn Sie beliebig lange Daten ohne Padding verschlüsseln wollen oder zu anderen Systemen kompatibel sein müssen, die CTR verwenden. Der Modus bietet aber keine Integritätsprüfung: Ein Angreifer kann einzelne Bits im Geheimtext unbemerkt umkippen. Für neue Anwendungen ist daher meist AES-GCM die bessere Wahl. Wenn Sie trotzdem CTR verwenden, sichern Sie die Daten zusätzlich mit einem MAC ab, zum Beispiel HMAC.

Wichtig: Zum Entschlüsseln müssen exakt dieselben Werte für counter und length verwendet werden wie beim Verschlüsseln. Der Zählerblock ist nicht geheim und wird üblicherweise zusammen mit dem Geheimtext gespeichert oder übertragen.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Muss "AES-CTR" sein. Groß-/Kleinschreibung wird nicht beachtet.
$counter Pflicht ArrayBuffer | TypedArray | DataView Der anfängliche Zählerblock, genau 16 Byte lang (eine AES-Blockgröße). Die oberen Bits bilden die Nonce, die unteren length Bits den Zähler, der hochgezählt wird. Mit demselben Schlüssel darf der Zählerblock niemals wiederverwendet werden.
$length Pflicht number Anzahl der Bits im Zählerblock (1–128), die als eigentlicher Zähler dienen. Die restlichen 128 - length Bits bleiben als Nonce unverändert. Üblich ist 64. Läuft der Zähler über, wirft der Browser einen OperationError.

Rückgabewert

Typ
void
Beschreibung
AesCtrParams ist ein reines Parameter-Objekt ohne eigenen Rückgabewert. Die Methoden, die es verwenden, geben ein Promise<ArrayBuffer> (encrypt/decrypt/wrapKey) bzw. ein Promise<CryptoKey> (unwrapKey) zurück.

Beispiele

Text mit AES-CTR verschlüsseln und wieder entschlüsseln

const key = await crypto.subtle.generateKey(
  { name: 'AES-CTR', length: 256 },
  true,
  ['encrypt', 'decrypt']
);

// 16-Byte-Zählerblock: zufällige Nonce, die unteren 64 Bit dienen als Zähler
const counter = crypto.getRandomValues(new Uint8Array(16));
const params = { name: 'AES-CTR', counter, length: 64 };

const plaintext = new TextEncoder().encode('Geheime Nachricht');
const ciphertext = await crypto.subtle.encrypt(params, key, plaintext);
console.log('Länge Geheimtext:', ciphertext.byteLength);

// Entschlüsseln mit exakt denselben Parametern
const decrypted = await crypto.subtle.decrypt(params, key, ciphertext);
console.log(new TextDecoder().decode(decrypted));
Länge Geheimtext: 17 Geheime Nachricht

Zählerblock zusammen mit dem Geheimtext speichern

const encryptPacked = async (key, text) => {
  const counter = crypto.getRandomValues(new Uint8Array(16));
  const data = new TextEncoder().encode(text);
  const ct = new Uint8Array(
    await crypto.subtle.encrypt({ name: 'AES-CTR', counter, length: 64 }, key, data)
  );
  // Format: [16 Byte Zählerblock | Geheimtext]
  const packed = new Uint8Array(16 + ct.length);
  packed.set(counter, 0);
  packed.set(ct, 16);
  return packed;
};

const decryptPacked = async (key, packed) => {
  const counter = packed.slice(0, 16);
  const ct = packed.slice(16);
  const pt = await crypto.subtle.decrypt({ name: 'AES-CTR', counter, length: 64 }, key, ct);
  return new TextDecoder().decode(pt);
};

const key = await crypto.subtle.generateKey({ name: 'AES-CTR', length: 128 }, false, ['encrypt', 'decrypt']);
const blob = await encryptPacked(key, 'Hallo Welt');
console.log(blob.length);
console.log(await decryptPacked(key, blob));
26 Hallo Welt

Einen Schlüssel mit AES-CTR ein- und auspacken (wrapKey/unwrapKey)

const wrappingKey = await crypto.subtle.generateKey(
  { name: 'AES-CTR', length: 256 }, false, ['wrapKey', 'unwrapKey']
);
const hmacKey = await crypto.subtle.generateKey(
  { name: 'HMAC', hash: 'SHA-256' }, true, ['sign', 'verify']
);

const counter = crypto.getRandomValues(new Uint8Array(16));
const params = { name: 'AES-CTR', counter, length: 64 };

const wrapped = await crypto.subtle.wrapKey('raw', hmacKey, wrappingKey, params);

const restored = await crypto.subtle.unwrapKey(
  'raw', wrapped, wrappingKey, params,
  { name: 'HMAC', hash: 'SHA-256' }, true, ['sign', 'verify']
);
console.log(restored.algorithm.name, restored.type);
HMAC secret

// Wichtig · Fallstricke

  • Zählerblock niemals wiederverwenden: Wird dieselbe Kombination aus Schlüssel und counter für zwei Nachrichten verwendet, kann ein Angreifer per XOR der beiden Geheimtexte Rückschlüsse auf die Klartexte ziehen. Erzeugen Sie für jede Nachricht eine neue Nonce, zum Beispiel mit crypto.getRandomValues().
  • Keine Authentifizierung: AES-CTR erkennt keine Manipulation. Ein falscher Schlüssel oder ein veränderter Geheimtext führt nicht zu einem Fehler, sondern nur zu unbrauchbaren Daten. Verwenden Sie AES-GCM oder sichern Sie die Daten zusätzlich mit HMAC ab (Encrypt-then-MAC).
  • counter muss exakt 16 Byte lang sein und length zwischen 1 und 128 liegen. Sonst wird das Promise mit einem OperationError abgelehnt. Ein kleines length begrenzt die maximale Datenmenge pro Nachricht auf 2length Blöcke à 16 Byte.
  • Die Parameter counter und length gehören zu AesCtrParams. Nicht verwechseln mit length in AesKeyGenParams: Dort steht es für die Schlüssellänge (128/192/256).
  • Kompatibilität: crypto.subtle ist nur in einem sicheren Kontext (HTTPS oder localhost) verfügbar. Alle modernen Browser unterstützen AES-CTR, ebenso Node.js ab Version 15 über globalThis.crypto.subtle bzw. require('node:crypto').webcrypto.