Web Cryptography API
The Web Cryptography API provides basic cryptographic operations in web applications, such as hashing, signature generation and verification, and encryption and decryption.
The Web Cryptography API allows a number of important security scenarios for web apps. These range from robust user/service authentication, document and code signing, and the confidentiality and integrity of communications all without requiring a secure connection (through SSL or similar protocol). Specifically, you can use the Web Cryptography API for:
- Multi-factor authentication
- Protected document exchange
- Cloud storage
- Document signing
- Data integrity protection
- Secure messaging
Web Cryptography in Microsoft Edge
Since its initial implementation in Internet Explorer 11, the World Wide Web Consortium (W3C) specification has changed from an event-driven model to a new model based on JavaScript Promises. The Microsoft Edge implementation has been updated to reflect these changes and removes support for the legacy event-based model.
For more info, see Web Cryptography API updates
Web Cryptography in IE11
The following example works only with the IE11 implementation of Web Cryptography API and illustrates how to use this API to generate a key pair, sign a piece of data with the private key and verify the signature using the public key.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Web Cryptography API - Signing Data</title>
</head>
<body>
<script>
// WARNING: The following code works only in IE11
var pubKey;
var privKey;
var data = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); // The data to be signed.
var encryptedData;
var decryptedData;
var crypto = window.crypto || window.msCrypto;
if (crypto.subtle) {
var genOp = crypto.subtle.generateKey(
{ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([0x01, 0x00, 0x01]) },
false,
["encrypt", "decrypt"]);
genOp.onerror = function (e) { console.log("genOp.onerror event handler fired."); }
genOp.oncomplete = function (e) {
pubKey = e.target.result.publicKey;
privKey = e.target.result.privateKey;
if (pubKey && privKey) {
console.log("generateKey RSASSA-PKCS1-v1_5: PASS");
} else {
console.log("generateKey RSASSA-PKCS1-v1_5: FAIL");
} // if-else
var signkey = crypto.subtle.sign({ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, privKey, data);
signkey.onerror = function (evt) {
console.log("signkey.onerror event handler fired.");
}
signkey.oncomplete = function (evt) {
signature = evt.target.result;
if (signature) {
console.log("Sign with RSASSA-PKCS1-v1_5 - SHA-256: PASS");
} else {
console.log("Sign with RSASSA-PKCS1-v1_5 - SHA-256: FAIL");
}
var verifysig = crypto.subtle.verify({ name: "RSASSA-PKCS1-v1_5", hash: "SHA-256"}, pubKey, signature, data);
verifysig.onerror = function (evt) {
console.log("Verify verifysig.onerror event handler fired.");
}
verifysig.oncomplete = function (evt) {
var verified = evt.target.result;
if (verified) {
console.log("Verify Operation for RSASSA-PKCS1-v1_5 - SHA-256: PASS");
} else {
console.log("Verify Operation for RSASSA-PKCS1-v1_5 - SHA-256: FAIL");
} // if-else
}; // verifysig.oncomplete
}; // signkey.oncomplete
}; // genOp.oncomplete
} else {
console.log("Unable to create window.crypto object");
} // if-else, (crypto.subtle)
</script>
</body>
</html>