SubtleCrypto: sign()-Methode
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
* Some parts of this feature may have varying levels of support.
Sicherer Kontext: Diese Funktion ist nur in sicheren Kontexten (HTTPS) in einigen oder allen unterstützenden Browsern verfügbar.
Hinweis: Diese Funktion ist in Web Workers verfügbar.
Die sign()
-Methode der SubtleCrypto
Schnittstelle generiert eine digitale Signatur.
Sie nimmt als Argumente einen Schlüssel zum Signieren, einige algorithmusspezifische Parameter und die zu signierenden Daten. Sie gibt ein Promise
zurück, das mit der Signatur erfüllt wird.
Sie können die entsprechende SubtleCrypto.verify()
-Methode verwenden, um die Signatur zu überprüfen.
Syntax
sign(algorithm, key, data)
Parameter
algorithm
-
Ein String oder Objekt, das den zu verwendenden Signaturalgorithmus und seine Parameter spezifiziert:
- Um RSASSA-PKCS1-v1_5 zu verwenden, übergeben Sie den String
RSASSA-PKCS1-v1_5
oder ein Objekt der Form{ name: "RSASSA-PKCS1-v1_5" }
. - Um RSA-PSS zu verwenden, übergeben Sie ein
RsaPssParams
-Objekt. - Um ECDSA zu verwenden, übergeben Sie ein
EcdsaParams
-Objekt. - Um HMAC zu verwenden, übergeben Sie den String
HMAC
oder ein Objekt der Form{ name: "HMAC" }
. - Um Ed25519 zu verwenden, übergeben Sie den String
Ed25519
oder ein Objekt der Form{ name: "Ed25519" }
.
- Um RSASSA-PKCS1-v1_5 zu verwenden, übergeben Sie den String
key
-
Ein
CryptoKey
-Objekt, das den Schlüssel zum Signieren enthält. Wennalgorithm
ein öffentlich-verschlüsseltes Kryptosystem identifiziert, ist dies der private Schlüssel. data
-
Ein
ArrayBuffer
, einTypedArray
oder einDataView
-Objekt, das die zu signierenden Daten enthält.
Rückgabewert
Ein Promise
, das mit einem ArrayBuffer
erfüllt wird, das die Signatur enthält.
Ausnahmen
Das Promise wird abgelehnt, wenn die folgende Ausnahme auftritt:
InvalidAccessError
DOMException
-
Wird ausgelöst, wenn der Signaturschlüssel kein Schlüssel für den angeforderten Signaturalgorithmus ist oder wenn versucht wird, einen Algorithmus zu verwenden, der entweder unbekannt ist oder sich nicht zum Signieren eignet.
Unterstützte Algorithmen
Die Web Crypto API bietet folgende Algorithmen, die zum Signieren und zur Signaturüberprüfung verwendet werden können.
RSASSA-PKCS1-v1_5, RSA-PSS, ECDSA und Ed25519 sind öffentlich-verschlüsselte Kryptosysteme, die den privaten Schlüssel zum Signieren und den öffentlichen Schlüssel zur Überprüfung verwenden. Diese Systeme verwenden alle einen Hash-Algorithmus, um die Nachricht vor dem Signieren auf eine kurze feste Größe zu reduzieren.
- Für RSASSA-PKCS1-v1_5 und RSA-PSS wird die Wahl des Hash-Algorithmus in die Funktionen
generateKey()
oderimportKey()
übergeben. - Für ECDSA ist die Wahl des Hash-Algorithmus im
algorithm
-Parameter enthalten, der in diesign()
-Funktion übergeben wird. - Für Ed25519 ist der Hash-Algorithmus immer SHA-512.
Der HMAC-Algorithmus unterscheidet sich von den anderen darin, dass er kein öffentlich-verschlüsseltes Kryptosystem ist: Er verwendet denselben Algorithmus und Schlüssel sowohl zum Signieren als auch zur Überprüfung. Das bedeutet, dass der Überprüfungsschlüssel geheim gehalten werden muss, was wiederum bedeutet, dass dieser Algorithmus für viele Signaturnutzungsfälle nicht geeignet ist. Er kann jedoch eine gute Wahl sein, wenn der Unterzeichner und der Prüfer dieselbe Entität sind.
RSASSA-PKCS1-v1_5
Der RSASSA-PKCS1-v1_5-Algorithmus ist in RFC 3447 spezifiziert.
RSA-PSS
Der RSA-PSS-Algorithmus ist in RFC 3447 spezifiziert.
Er unterscheidet sich von RSASSA-PKCS1-v1_5 darin, dass er ein zufälliges Salt bei der Signaturoperation einbezieht, sodass dieselbe Nachricht, die mit demselben Schlüssel signiert wird, nicht jedes Mal zu derselben Signatur führt. Eine zusätzliche Eigenschaft, die die Salt-Länge definiert, wird in die sign()
- und verify()
-Funktionen übergeben, wenn sie aufgerufen werden.
ECDSA
ECDSA (Elliptic Curve Digital Signature Algorithm) ist eine Variante des Digital Signature Algorithmus, spezifiziert in FIPS-186, die Elliptische-Kurven-Kryptographie verwendet (RFC 6090).
Signaturen werden als die s1
- und s2
-Werte codiert, die in RFC 6090 spezifiziert sind (jeweils bekannt als r
und s
in RFC 4754), jeweils in Big-Endian-Byte-Arrays, mit ihrer Länge als Bitgröße der Kurve aufgerundet auf eine ganze Anzahl von Bytes.
Diese Werte werden in dieser Reihenfolge miteinander verkettet.
Diese Codierung wurde auch von der IEEE 1363-2000-Norm vorgeschlagen und wird manchmal als IEEE P1363-Format bezeichnet. Sie unterscheidet sich von der X.509-Signaturstruktur, die das Standardformat ist, das von einigen Tools und Bibliotheken wie OpenSSL erzeugt wird.
Ed25519
Ed25519 ist ein digitaler Signaturalgorithmus, der auf der Elliptischen Kurve Curve25519 basiert, die Teil der Edwards-Curve Digital Signature Algorithm (EdDSA)-Familie von Algorithmen ist, die in RFC 8032 definiert sind.
HMAC
Der HMAC-Algorithmus berechnet und überprüft Hash-basierte Nachrichten-Authentifizierungs-Codes gemäß dem FIPS 198-1 Standard (PDF).
Der zu verwendende Hash-Algorithmus wird im HmacKeyGenParams
-Objekt angegeben, das Sie in die generateKey()
-Funktion übergeben, oder im HmacImportParams
-Objekt, das Sie in die importKey()
-Funktion übergeben.
Der HMAC-Algorithmus verwendet denselben Algorithmus und Schlüssel sowohl zum Signieren als auch zur Überprüfung: Dies bedeutet, dass der Überprüfungsschlüssel geheim gehalten werden muss, was wiederum bedeutet, dass dieser Algorithmus für viele Signaturnutzungsfälle nicht geeignet ist. Er kann jedoch eine gute Wahl sein, wenn der Unterzeichner und der Prüfer dieselbe Entität sind.
Beispiele
Hinweis: Sie können die funktionierenden Beispiele auf GitHub ausprobieren.
RSASSA-PKCS1-v1_5
Dieser Code ruft den Inhalt eines Textfeldes ab, kodiert ihn zum Signieren und signiert ihn mit einem privaten Schlüssel. Sehen Sie den vollständigen Quellcode auf GitHub.
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = document.querySelector(".rsassa-pkcs1 #message");
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}
let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
"RSASSA-PKCS1-v1_5",
privateKey,
encoded,
);
RSA-PSS
Dieser Code ruft den Inhalt eines Textfeldes ab, kodiert ihn zum Signieren und signiert ihn mit einem privaten Schlüssel. Sehen Sie den vollständigen Quellcode auf GitHub.
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = document.querySelector(".rsa-pss #message");
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}
let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
{
name: "RSA-PSS",
saltLength: 32,
},
privateKey,
encoded,
);
ECDSA
Dieser Code ruft den Inhalt eines Textfeldes ab, kodiert ihn zum Signieren und signiert ihn mit einem privaten Schlüssel. Sehen Sie den vollständigen Quellcode auf GitHub.
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = document.querySelector(".ecdsa #message");
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}
let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign(
{
name: "ECDSA",
hash: { name: "SHA-384" },
},
privateKey,
encoded,
);
HMAC
Dieser Code ruft den Inhalt eines Textfeldes ab, kodiert ihn zum Signieren und signiert ihn mit einem geheimen Schlüssel. Sehen Sie den vollständigen Quellcode auf GitHub.
/*
Fetch the contents of the "message" textbox, and encode it
in a form we can use for the sign operation.
*/
function getMessageEncoding() {
const messageBox = document.querySelector(".hmac #message");
let message = messageBox.value;
let enc = new TextEncoder();
return enc.encode(message);
}
let encoded = getMessageEncoding();
let signature = await window.crypto.subtle.sign("HMAC", key, encoded);
Ed25519 (Schlüsselerzeugung, Signierung und Verifizierung)
Dieser Code generiert ein Ed25519-Signierschlüsselpaar, verwendet den privaten Schlüssel, um den kodierten Inhalt eines Textes <input>
zu signieren, und überprüft dann die Signatur mit dem öffentlichen Schlüssel.
Er stammt von diesem Quellcode auf GitHub., den Sie hier live ausführen können.
HTML
Das HTML definiert ein <input>
-Element, das den zu signierenden Text enthält, und eine Schaltfläche, die die Operation zum Erstellen der Schlüssel, Signieren des Textes und anschließendes Überprüfen der Signatur startet.
<label for="message">Enter a message to sign:</label>
<input
type="text"
id="message"
name="message"
size="25"
value="The lion roars near dawn" />
<input id="sign-button" type="button" value="Run" />
JavaScript
Das JavaScript holt zuerst die #sign-button
- und #message
-<input>
-Elemente und fügt dann einen Listener für das click
-Ereignis auf der Schaltfläche hinzu.
Der Ereignishandler löscht das Log und führt die anderen Operationen aus, indem er den Inhalt des <input>
-Elements übergibt.
const button = document.querySelector("#sign-button");
const input = document.querySelector("#message");
button.addEventListener("click", () => {
// Clear log
logElement.innerText = "";
logElement.scrollTop = logElement.scrollHeight;
// Run test
test(input.value);
});
Zuerst werden Schlüssel mit dem Ed25519-Algorithmus generiert, dann wird Text kodiert und dieser Text mit dem privaten Schlüssel signiert.
Schließlich wird SubtleCrypto.verify()
mit dem öffentlichen Schlüssel aufgerufen, um die Signatur zu überprüfen.
async function test(data) {
log(`Message: ${data}`);
try {
// Generate keys
const { publicKey, privateKey } = await crypto.subtle.generateKey(
{
name: "Ed25519",
},
true,
["sign", "verify"],
);
log(`publicKey: ${publicKey}, type: ${publicKey.type}`);
log(`privateKey: ${privateKey}, type: ${privateKey.type}`);
// Encode data prior to signing
const encoder = new TextEncoder();
encodedData = encoder.encode(data);
// Log the first part of the encoded data
const shorterEncodedBuffer = new Uint8Array(encodedData.buffer, 0, 14);
log(
`encodedData: ${shorterEncodedBuffer}...[${encodedData.byteLength} bytes total]`,
);
//log(`encodedData: ${encodedData}`);
// Sign the data using the private key.
const signature = await crypto.subtle.sign(
{
name: "Ed25519",
},
privateKey,
encodedData,
);
// Log the first part of the signature data
const signatureBuffer = new Uint8Array(signature, 0, 14);
log(
`signature: ${signatureBuffer}...[${signature.byteLength} bytes total]`,
);
// Verify the signature using the public key
const verifyResult = await crypto.subtle.verify(
{
name: "Ed25519",
},
publicKey,
signature,
encodedData,
);
// Log result - true if the text was signed with the corresponding public key.
log(`signature verified?: ${verifyResult}`);
} catch (error) {
log(error);
}
}
Ergebnis
Spezifikationen
Specification |
---|
Web Cryptography API # SubtleCrypto-method-sign |
Browser-Kompatibilität
Siehe auch
SubtleCrypto.verify()
.- RFC 3447 spezifiziert RSASSA-PKCS1-v1_5.
- RFC 3447 spezifiziert RSA-PSS.
- FIPS-186 spezifiziert ECDSA.
- FIPS 198-1 spezifiziert HMAC.