この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: keygen要素
SEOタイトル: HTML keygen 要素完全ガイド(HTML5.2 で廃止、WebAuthn / Web Crypto への移行)

この記事の要点
  • <keygen> はクライアント証明書要求の生成用要素。クライアント側で鍵ペア生成 → 公開鍵を送信
  • HTML 5.2 で deprecated、HTML 5.3 で完全削除。2026 年現在どのブラウザでも動かない
  • Chrome 49、Firefox 69、Opera 36 で削除済。Safari は最後まで動いていたが現代は非対応
  • 代替1: WebAuthn (FIDO2) — 公開鍵暗号方式によるパスワードレス認証
  • 代替2: Web Crypto API (SubtleCrypto) — JavaScript で鍵生成 / 署名
  • SSL クライアント証明書発行は、サーバ側で CSR を生成するか端末側で OpenSSL を使う方式が主流

<keygen> 要素とは

HTML4.01 〜 HTML5 初期に存在した、クライアントブラウザで公開鍵 / 秘密鍵ペアを生成し、公開鍵をサーバへ送信するためのフォーム要素です。SSL/TLS クライアント証明書の発行や PKI 環境の構築に使われていました。

<!-- 廃止済の文法 (現在動かない) -->
<form action="/issue-cert" method="POST">
  <p>キー長を選択:</p>
  <keygen name="public_key" keytype="RSA" challenge="ランダム文字列">
  <input type="submit" value="証明書発行">
</form>

送信時の挙動:

  1. ブラウザがクライアント側で鍵ペアを生成 (RSA 2048bit など)
  2. 秘密鍵をローカルの鍵ストアに保存
  3. 公開鍵 + チャレンジを SPKAC (Signed Public Key And Challenge) 形式でエンコード
  4. SPKAC を Base64 化してサーバへ送信
  5. サーバが PKCS#10 として処理して証明書 (X.509) を発行

廃止の経緯

時期出来事
1995 〜Netscape Navigator が独自仕様として実装
2014HTML5 (W3C) に標準として収録
2016Chrome 49 で削除 (Blink チームによる廃止判断)
2017HTML 5.2 でdeprecated マーキング
2017Firefox 51〜69 で段階的削除
2019HTML 5.3 で完全削除
2020 以降Safari / Edge も非対応

廃止理由 (Chrome の開発者コメント)

  • UI が古くブラウザごとに挙動が異なる (鍵長選択 UI が無い等)
  • 仕様が過去 30 年ほぼ更新されていない (古い MD5/SHA-1 ベース)
  • セキュリティ的にSPKAC は安全性が低い — 現代の TLS スタックには不適
  • 実利用が極めて少ない — 統計で 0.001% 未満
  • 同じ機能がWeb Crypto API でより柔軟に実現可能

代替手段 1: WebAuthn (FIDO2)

パスワードレス認証の標準。ブラウザがハードウェア (Yubikey / Touch ID / Windows Hello) や Passkey と連携し、公開鍵ベースで認証します。

// 登録 (公開鍵生成 + サーバへ送信)
const credential = await navigator.credentials.create({
  publicKey: {
    challenge: new Uint8Array(32),   // サーバから受け取ったランダム値
    rp: { name: "Example", id: "example.com" },
    user: {
      id: new TextEncoder().encode("user-123"),
      name: "alice@example.com",
      displayName: "Alice"
    },
    pubKeyCredParams: [
      { type: "public-key", alg: -7  },  // ES256
      { type: "public-key", alg: -257 }, // RS256
    ],
    authenticatorSelection: {
      authenticatorAttachment: "platform",  // platform | cross-platform
      userVerification: "required"
    },
    timeout: 60000,
    attestation: "direct"
  }
});

// credential.response.attestationObject をサーバへ送信
// サーバ側で検証してユーザーに公開鍵を紐付ける

// ログイン
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: new Uint8Array(32),
    allowCredentials: [{
      type: "public-key",
      id: storedCredentialId
    }],
    userVerification: "required"
  }
});

主要ブラウザはすべて対応済 (Chrome / Firefox / Safari / Edge)。2024 年以降は Passkey として OS 標準機能に統合されています。

代替手段 2: Web Crypto API (SubtleCrypto)

JavaScript から直接鍵を生成 / 署名 / 暗号化できる W3C 標準 API。<keygen> 相当の処理は SubtleCrypto で自前実装できます。

// RSA 鍵ペア生成
const keyPair = await crypto.subtle.generateKey(
  {
    name: "RSASSA-PKCS1-v1_5",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  },
  true,                          // extractable (export 可)
  ["sign", "verify"]
);

// 公開鍵を SPKI 形式でエクスポート
const publicKeyDer = await crypto.subtle.exportKey("spki", keyPair.publicKey);
const publicKeyBase64 = btoa(String.fromCharCode(...new Uint8Array(publicKeyDer)));

// サーバへ送信
await fetch("/api/register-key", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ public_key: publicKeyBase64 })
});

// 秘密鍵で署名
const signature = await crypto.subtle.sign(
  "RSASSA-PKCS1-v1_5",
  keyPair.privateKey,
  new TextEncoder().encode("メッセージ")
);

// 秘密鍵は IndexedDB に extractable=false で保存するのが安全

代替手段 3: サーバ側 CSR 生成 + クライアント証明書配布

多くのエンタープライズ環境では、もう <keygen> ではなく以下の方式が一般的:

  • サーバ側で CSR と鍵を生成 → PKCS#12 (.p12) ファイルで配布 → ユーザーがブラウザ / OS にインポート
  • SCEP / EST / ACME などプロトコルベースの自動配布 (社内 PKI)
  • MDM (Mobile Device Management) からプッシュ配布 (iOS / Android の社用端末)
# OpenSSL でクライアント鍵 + CSR 生成 (端末側)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr \
  -subj "/C=JP/CN=alice@example.com"

# サーバ管理者が CA で署名 → client.crt が返ってくる
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out client.crt -days 365 -sha256

# PKCS#12 にまとめる (ブラウザにインポート可能な形式)
openssl pkcs12 -export -inkey client.key -in client.crt \
  -out client.p12 -name "Alice"

# ブラウザに p12 をインポート (Chrome の場合)
# 設定 → プライバシーとセキュリティ → 証明書の管理 → インポート

歴史的経緯: PKI と SSL クライアント証明書

<keygen> は 1995 年に Netscape が独自実装し、その後 W3C / WHATWG に標準化されました。ブラウザでクライアント証明書を発行する PKI ワークフローを目的としたものですが、UI 統一困難・低利用率・セキュリティ要件のミスマッチから廃止されました。現代では:

  • 個人認証 → WebAuthn / Passkey
  • API 認証 → OAuth2 / JWT / mTLS
  • ファイル暗号 / 署名 → Web Crypto API
  • クライアント証明書配布 → MDM / SCEP / EST

FAQ

Q: 既存システムが <keygen> に依存している
A: 既存ブラウザでは動かないため、Web Crypto API + 自前 SPKAC エミュレーション、または WebAuthn への移行が必要です。古い IE11 や Firefox ESR の極一部にのみ残っている場合があります。

Q: Safari は最後まで動いていた?
A: macOS Safari は比較的長く残しましたが、macOS Big Sur / iOS 14 以降で削除されています。

Q: WebAuthn と Passkey の関係は?
A: WebAuthn が下位プロトコル仕様、Passkey は WebAuthn を OS / iCloud / Google アカウント間で同期する具体的なユーザー体験です。