Table of Contents#
- Introduction
- What is the HTML
<keygen>Tag? - Syntax and Attributes
- Example Usage
- Historical Common Practices
- Deprecation and Best Practices
- Alternatives to
<keygen> - Conclusion
- References
What is the HTML <keygen> Tag?#
The <keygen> element was an HTML form control that generated a public-private key pair when a form was submitted. The public key was sent to the server, while the private key remained on the client (stored in the browser’s key store). It aimed to enable:
- Secure client authentication (e.g., client-side TLS certificates).
- Encryption/decryption of form data using client-generated keys.
How It Worked#
When a form with <keygen> was submitted, the browser:
- Generated an RSA key pair (by default, though
keytypeallowed other algorithms in theory). - Sent the public key (or a certificate signing request, CSR) to the server via the form.
- Stored the private key in the browser’s key store (e.g., for later use in authentication).
Syntax and Attributes#
The <keygen> tag is a void element (no closing tag) and was used inside <form> elements. It supported the following attributes:
| Attribute | Description |
|---|---|
name | (Required) Name of the control (used in form data submission). |
challenge | A string signed with the private key (used to verify key origin). |
keytype | Key algorithm (only rsa was widely supported; others were non-standard). |
disabled | Disables the keygen control. |
form | Associates the control with a form (if not a direct child of <form>). |
autofocus | Automatically focuses the control on page load. |
Example Usage#
Here’s a historical example of a form using <keygen> to generate an RSA key pair for client authentication:
<!DOCTYPE html>
<html>
<body>
<form action="submit_key.php" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<!-- Generate an RSA key pair -->
<keygen name="clientKey" keytype="rsa" challenge="random_challenge_123">
<input type="submit" value="Submit Key">
</form>
</body>
</html>When submitted, the browser generated an RSA key pair. The public key (in a signed format, e.g., a CSR) was sent to submit_key.php, while the private key remained in the browser.
Historical Common Practices#
The <keygen> tag was primarily used in:
- Enterprise Client Authentication: Corporate intranets used it to generate client-side TLS certificates. The server would sign the client’s public key (via a CSR) and issue a certificate for secure access.
- Secure Form Submissions: For encrypting sensitive data (e.g., financial forms) using client-generated keys.
Deprecation and Best Practices#
Why Deprecated?#
- Browser Support: Modern browsers (Chrome, Firefox, Safari, Edge) have deprecated or removed
<keygen>due to low adoption and security risks. - Security Issues:
- Inconsistent key generation across browsers led to vulnerabilities.
- Storing private keys in the browser’s key store exposed them to malicious scripts.
- Better Alternatives: Modern web standards (e.g., WebCrypto API) offer more secure, flexible key management.
Best Practices (Now)#
- Avoid
<keygen>entirely—it is not supported in modern browsers and poses security risks. - Use modern cryptographic methods (e.g., WebCrypto API, server-side key generation) for secure key management.
Alternatives to <keygen>#
1. WebCrypto API#
The WebCrypto API is a JavaScript API for secure cryptographic operations (key generation, signing, encryption). It is supported in all modern browsers.
Example: Generate an RSA Key Pair with WebCrypto#
async function generateRSAKeyPair() {
const keyPair = await window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048, // Key length (2048+ bits recommended)
publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // 65537
hash: "SHA-256", // Hashing algorithm for OAEP
},
true, // Extractable (for signing/encryption)
["encrypt", "decrypt"] // Key usage
);
return keyPair;
}
// Usage:
generateRSAKeyPair().then((keyPair) => {
console.log("Public Key:", keyPair.publicKey);
console.log("Private Key:", keyPair.privateKey);
});2. Server-Side Key Generation#
Generate keys on the server (e.g., using Node.js crypto or Python’s cryptography library) and transmit them securely to the client via TLS.
Example: Node.js Server-Side Key Generation#
const crypto = require('crypto');
// Generate an RSA key pair
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
publicKeyEncoding: { type: 'spki', format: 'pem' },
privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
});
console.log("Public Key (PEM):", publicKey);
console.log("Private Key (PEM):", privateKey);3. Cryptographic Libraries#
Use JavaScript libraries like Forge or SJCL for simpler cryptographic operations (though WebCrypto is preferred for native browser support).
Conclusion#
The <keygen> tag was a historical tool for client-side key generation but is now deprecated due to security issues and lack of browser support. Modern web development demands secure, standardized cryptographic methods like the WebCrypto API or server-side key generation. When building secure applications, prioritize these modern alternatives to ensure compatibility, security, and reliability.
References#
- MDN Web Docs:
<keygen>Element - MDN Web Docs: WebCrypto API
- HTML Standard: Deprecation of
<keygen> - RFC 8017: RSA Cryptography (for RSA key specifications)