OpenSSL genpkey で作る各種アルゴリズム秘密鍵の詳細解説
はじめに
デジタル社会において、通信の秘匿性、データの完全性、および送信者の認証は不可欠です。これらを支える根幹技術の一つが公開鍵暗号方式です。公開鍵暗号では、互いに数学的に関連付けられた「秘密鍵」と「公開鍵」のペアを使用します。公開鍵は広く配布できますが、秘密鍵は所有者のみが厳重に管理する必要があります。秘密鍵は、暗号化されたデータを復号したり、デジタル署名を作成したりするために使用されます。
OpenSSLは、SSL/TLSプロトコルの実装をはじめ、公開鍵暗号やハッシュ関数、証明書管理など、暗号化技術に関する様々な機能を提供するオープンソースのツールキットです。その中でも openssl genpkey
コマンドは、公開鍵暗号方式で使用される秘密鍵を生成するための汎用的なツールとして非常に広く利用されています。
かつて、OpenSSLで秘密鍵を生成する際には、アルゴリズムごとに openssl rsa
, openssl dsa
, openssl ecparam
, openssl dhparam
などの専用コマンドを使用するのが一般的でした。しかし、genpkey
コマンドはこれらの機能を統合し、単一のインターフェースで複数のアルゴリズムに対応できるよう設計されています。これにより、新しいアルゴリズムが追加された場合でも、同じコマンド体系で扱える柔軟性が生まれました。
この記事では、openssl genpkey
コマンドを使用して生成できる主要な公開鍵暗号アルゴリズム(RSA、EC、DH、DSA、XDH、EdDSAなど)の秘密鍵について、その原理、鍵の構造、生成方法、および関連する詳細なオプションについて解説します。秘密鍵の適切な管理と運用についても触れ、安全な公開鍵インフラストラクチャの構築に役立つ情報を提供します。
openssl genpkey コマンドの基本
openssl genpkey
コマンドは、秘密鍵を生成するための主要なオプションを共通で持ちつつ、指定されたアルゴリズムに応じて固有のオプション(pkeyopt)を適用できる柔軟な設計になっています。
基本的なコマンド構文は以下の通りです。
bash
openssl genpkey [options]
主要なオプションとその役割を見ていきましょう。
-algorithm <alg>
: 必須。生成する秘密鍵のアルゴリズムを指定します。例えば、RSA
,EC
,DH
,DSA
,X25519
,Ed25519
などです。-out <file>
: 生成された秘密鍵を保存するファイルパスを指定します。指定しない場合、標準出力に出力されます。-pkeyopt <opt:value>
: アルゴリズム固有のパラメータを指定します。例えば、RSA鍵のビット長 (rsa_keygen_bits
) やEC鍵の曲線名 (ec_paramgen_curve
) などです。複数のパラメータを指定する場合は、-pkeyopt
を繰り返し使用します。-aes128
,-aes192
,-aes256
,-camellia128
,-camellia192
,-camellia256
,-des
,-des3
,-seed
: 生成される秘密鍵をパスフレーズで暗号化する場合に、使用する暗号アルゴリズムを指定します。これにより、秘密鍵ファイルが盗まれても、パスフレーズがなければ内容を読み取れません。-pass <arg>
: 秘密鍵を暗号化/復号する際のパスフレーズを指定する方法です。以下の形式があります。pass:<value>
: コマンドラインに直接パスフレーズを指定します。履歴に残る可能性があるため非推奨です。env:<var>
: 環境変数からパスフレーズを読み込みます。file:<path>
: ファイルからパスフレーズを読み込みます。stdin
: 標準入力からパスフレーズを読み込みます。最も安全な方法の一つです。auto
: OpenSSLにパスフレーズのプロンプトを表示させます。
-verbose
: 鍵生成処理の詳細な情報を表示します。-text
: 生成された秘密鍵のパラメータを人間が読みやすいテキスト形式でも表示します。秘密鍵の中身を確認する際に便利です。-traditional
: RSA秘密鍵を生成する際に、PKCS#1形式で出力します。デフォルトはPKCS#8形式です。他のアルゴリズムでも、可能であればアルゴリズム固有の伝統的な形式(例えばDSAの場合はPKCS#3 DSA)で出力する場合があります。-genparam
: 秘密鍵そのものではなく、そのアルゴリズムで使用するパラメータセットを生成します。DHやDSAなどで使用されます。生成されたパラメータは-out
で指定したファイルに保存され、後続のgenpkey
実行時に-paramfile
オプションで指定して鍵を生成します。-paramfile <file>
: パラメータセットを定義したファイル(-genparam
で生成したものなど)を指定して秘密鍵を生成します。
これらのオプションを組み合わせることで、目的に合った秘密鍵を柔軟に生成できます。次に、主要なアルゴリズムごとに秘密鍵の詳細と生成方法を見ていきましょう。
主要アルゴリズムとその秘密鍵の詳細
OpenSSLの genpkey
がサポートする主要な公開鍵暗号アルゴリズムについて、それぞれの秘密鍵の構造、生成方法、および考慮事項を詳しく解説します。
RSA (Rivest-Shamir-Adleman)
RSAは、公開鍵暗号アルゴリズムの中で最も古く、最も広く普及しているアルゴリズムの一つです。その安全性は、巨大な合成数の素因数分解の困難性に基づいています。
原理:
RSAの基本的な操作は、モジュラス n
を法としたべき乗剰余演算です。秘密鍵は、大きな素数 p
と q
を基に導出されます。公開鍵は (n, e)
のペア、秘密鍵は (n, d)
のペアとして表現されます(ただし、実際の秘密鍵ファイルには効率化のための追加情報が含まれます)。ここで、n = p * q
であり、e
は公開指数、d
は秘密指数です。e
と d
は、(e * d) ≡ 1 mod φ(n)
という関係を満たします。ここで φ(n)
はオイラーのトーシェント関数で、φ(n) = (p-1)(q-1)
です。
秘密鍵の構造:
RSA秘密鍵ファイルには、通常以下の情報が含まれます。
- modulus (n): 公開鍵と秘密鍵の演算で使用されるモジュラス。
p * q
です。 - publicExponent (e): 公開指数。 typically 3, 65537 (F4) or 2^16+1 (F3).
- privateExponent (d): 秘密指数。
d ≡ e^-1 mod φ(n)
。 - prime1 (p): n を構成する第一の素数。
- prime2 (q): n を構成する第二の素数。
- exponent1 (dp): d mod (p-1)。中国人剰余定理(CRT)を用いた計算を高速化するために使用されます。
- exponent2 (dq): d mod (q-1)。CRT用。
- coefficient (iq): (q^-1) mod p。CRT用。
これらのCRT関連パラメータ (dp, dq, iq) は、秘密鍵を使用した演算(復号や署名)の効率を向上させるために含まれます。秘密鍵ファイルの形式はPKCS#1またはPKCS#8が一般的です。PKCS#1は上記のパラメータを直接含み、PKCS#8はPrivateKeyInfo構造の中にアルゴリズムIDとオクテット列として秘密鍵パラメータをカプセル化します。
genpkeyでのRSA秘密鍵生成:
RSA鍵を生成するには、-algorithm RSA
を指定し、-pkeyopt
で鍵長を指定します。
“`bash
2048ビット長のRSA秘密鍵を生成し、key.pemに保存
openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
生成された鍵をパスフレーズで暗号化(AES-256を使用)
openssl genpkey -algorithm RSA -out encrypted_key.pem -aes256 -pass stdin -pkeyopt rsa_keygen_bits:2048
4096ビット長、公開指数65537のRSA秘密鍵を生成し、PKCS#1形式で出力
openssl genpkey -algorithm RSA -out traditional_key.pem -traditional -pkeyopt rsa_keygen_bits:4096 -pkeyopt rsa_keygen_pubexp:65537
詳細な鍵パラメータをテキスト表示
openssl genpkey -algorithm RSA -out key.pem -text -pkeyopt rsa_keygen_bits:2048
“`
-pkeyopt rsa_keygen_bits:<bits>
で鍵長を指定します。現在の推奨は2048ビット以上、より高いセキュリティレベルが必要な場合は3072ビット以上です。4096ビットも広く使用されています。
-pkeyopt rsa_keygen_pubexp:<exponent>
で公開指数を指定できます。一般的に使用されるのは 3
(F3) と 65537
(F4 = 2^16+1) です。F4がより計算効率が良く、推奨されています。
鍵長の影響:
- セキュリティ: 鍵長が長いほど、素因数分解が困難になり、セキュリティレベルが向上します。
- 生成時間: 鍵長が長いほど、鍵生成に時間がかかります。特に大きな素数を見つける処理に時間を要します。
- 処理速度: 暗号化、復号、署名、検証などの処理速度は、鍵長に依存します。通常、長い鍵ほど処理が遅くなります。特に秘密鍵を使用する復号や署名は、公開鍵を使用する暗号化や検証に比べて計算量が多くなりますが、CRTパラメータを用いることで効率化されています。
セキュリティ上の注意点:
- 十分な鍵長を選択すること。
- 素数の生成はランダム性の高い方法で行われること(OpenSSLは適切に行います)。
- 秘密鍵ファイルは厳重に管理し、必要に応じてパスフレーズで保護すること。
- サイドチャネル攻撃(鍵生成や署名/復号処理中の物理的な情報漏洩)に対する対策も考慮されるべきですが、これはOpenSSLの鍵生成ツール自体のスコープを超える場合が多いです。
EC (Elliptic Curve Cryptography)
楕円曲線暗号(ECC)は、離散対数問題の困難性を楕円曲線上の点に適用した公開鍵暗号アルゴリズムです。RSAと比較して、短い鍵長で同等のセキュリティレベルを提供できるという大きな利点があります。これにより、鍵サイズが小さくなり、計算負荷や帯域幅の削減につながります。
原理:
楕円曲線暗号は、有限体上の楕円曲線上の点と、その点に対する「スカラー倍算」(点を自分自身に繰り返し加算する操作)に基づいています。楕円曲線上の点 G
と秘密整数 d
が与えられたとき、点 Q = dG
を計算するのは比較的容易ですが、点 Q
と G
から秘密整数 d
を求めることは(特定の曲線では)非常に困難です。これが楕円曲線上の離散対数問題の困難性です。
ECCに基づく代表的なアルゴリズムには、デジタル署名に使用されるECDSA(Elliptic Curve Digital Signature Algorithm)や、鍵交換に使用されるECDH(Elliptic Curve Diffie-Hellman)があります。これらは同じタイプの秘密鍵を使用します。
秘密鍵の構造:
楕円曲線暗号の秘密鍵は、通常、以下の情報を含みます。
- 秘密整数 (d): 曲線上の基点
G
に対するスカラー倍数で、公開鍵点Q = dG
を計算します。 - 公開鍵点 (Q): 対応する公開鍵。
- 楕円曲線パラメータ: 秘密鍵と公開鍵が存在する楕円曲線を定義するパラメータセット(曲線名、体、係数、基点G、位数nなど)。これは秘密鍵ファイル自体に埋め込まれるか、または公開鍵ファイルに含められます。
秘密鍵ファイルはPKCS#8形式で表現されることが一般的です。
genpkeyでのEC秘密鍵生成:
EC鍵を生成するには、-algorithm EC
を指定し、-pkeyopt
で使用する楕円曲線を指定します。
“`bash
NIST P-256曲線(secp256r1)を使用したEC秘密鍵を生成
openssl genpkey -algorithm EC -out ec_key.pem -pkeyopt ec_paramgen_curve:prime256v1
NIST P-384曲線(secp384r1)を使用したEC秘密鍵を生成し、パスフレーズで暗号化
openssl genpkey -algorithm EC -out encrypted_ec_key.pem -aes256 -pass stdin -pkeyopt ec_paramgen_curve:secp384r1
鍵パラメータをテキスト表示
openssl genpkey -algorithm EC -out ec_key.pem -text -pkeyopt ec_paramgen_curve:secp256r1
まずパラメータファイルを作成し、それを用いて鍵を生成する例
NIST P-521曲線パラメータを生成
openssl genpkey -algorithm EC -genparam -out ec_param.pem -pkeyopt ec_paramgen_curve:secp521r1
生成したパラメータファイルを使用して秘密鍵を生成
openssl genpkey -paramfile ec_param.pem -out ec_key_from_param.pem
“`
-pkeyopt ec_paramgen_curve:<curve_name>
オプションで、使用する楕円曲線名を指定します。一般的に使用される標準曲線には以下のようなものがあります。
- NIST曲線:
prime256v1
(P-256, secp256r1),secp384r1
(P-384),secp521r1
(P-521)。これらはTLSや証明書などで広く使用されています。 - Brainpool曲線:
brainpoolP256r1
,brainpoolP384r1
,brainpoolP512r1
など。ヨーロッパで開発された曲線です。 - Curve25519 / Curve448: 後述するEdDSA/XDHで使用される特殊な曲線です。これらの曲線はECDSA/ECDHとは異なる数学構造を持ち、通常
-algorithm Ed25519
,-algorithm X25519
などとして独立して扱われます。
-genparam
オプションを使用すると、秘密鍵そのものではなく、特定の曲線定義を記述したパラメータファイルを作成できます。これは、同じパラメータセットを使って複数の鍵を生成する場合や、パラメータセットを共有する場合に便利です。
主要な楕円曲線とその特性:
- NIST P-256: 128ビット相当のセキュリティを提供し、最も広く普及している曲線の一つです。速度とセキュリティのバランスが良いとされます。
- NIST P-384: 192ビット相当のセキュリティを提供します。P-256よりも高いセキュリティが必要な場合に使用されます。
- NIST P-521: 256ビット相当のセキュリティを提供します。OpenSSLでは521ビットとして扱われます(実際には521ビット素数を法とする体を使用)。
Ed25519 / Ed448 (Edwards-curve Digital Signature Algorithm):
Ed25519とEd448は、Twisted Edwards曲線と呼ばれる特殊な楕円曲線上で定義されたデジタル署名アルゴリズムです。EdDSAは、ECDSAと比較して実装が容易で、計算が高速かつタイミング攻撃に対する耐性が高いという利点があります。これらは、OpenSSL 3.0以降で genpkey
の -algorithm
オプションとして直接サポートされています。
-
genpkeyでのEd25519/Ed448秘密鍵生成:
“`bash
Ed25519秘密鍵を生成
openssl genpkey -algorithm Ed25519 -out ed25519_key.pem
Ed448秘密鍵を生成
openssl genpkey -algorithm Ed448 -out ed448_key.pem
パスフレーズで暗号化
openssl genpkey -algorithm Ed25519 -out encrypted_ed25519_key.pem -aes256 -pass stdin
“`Ed25519およびEd448は、アルゴリズム自体に曲線パラメータが含まれているため、
-pkeyopt
で曲線名を指定する必要はありません。鍵生成は非常にシンプルです。
セキュリティ上の注意点:
- 使用する楕円曲線は、信頼できる標準(NIST, Brainpoolなど)によって定義されたものであること。自分でパラメータを生成することは推奨されません。
- サイドチャネル攻撃に対する耐性は、曲線の種類や実装に依存します。EdDSAは設計上、耐性が高いとされます。
- 秘密鍵ファイルは厳重に管理すること。
DH (Diffie-Hellman)
Diffie-Hellman(DH)鍵交換は、公開チャネル上で秘密の共有鍵を安全に確立するためのアルゴリズムです。その安全性は、有限体上の離散対数問題の困難性に基づいています。DH自体は暗号化や署名には使用されませんが、TLS/SSLハンドシェイクにおける鍵交換など、共有秘密を生成する重要な役割を果たします。
原理:
DH鍵交換では、まず大きな素数 p
とその原始根 g
という公開パラメータを合意します。アリスとボブが共有秘密を確立したい場合、アリスは秘密整数 a
を選び、公開値 A = g^a mod p
を計算してボブに送ります。ボブは秘密整数 b
を選び、公開値 B = g^b mod p
を計算してアリスに送ります。アリスは受け取った B
と自身の秘密鍵 a
を使って s = B^a mod p = (g^b)^a mod p = g^(ab) mod p
を計算します。ボブは受け取った A
と自身の秘密鍵 b
を使って s = A^b mod p = (g^a)^b mod p = g^(ab) mod p
を計算します。このようにして、アリスとボブは同じ秘密の共有鍵 s
を得ることができます。第三者は公開されている p
, g
, A
, B
から秘密の a
や b
、そして共有鍵 s
を知ることは困難です。
秘密鍵の構造:
DH秘密鍵は、以下の情報を含みます。
- パラメータ (p, g): 鍵交換で使用する大きな素数
p
と生成元g
。 - 秘密整数 (x): 鍵所有者のみが知る秘密の整数(上記原理の
a
またはb
に相当)。 - 公開値 (y): 秘密整数
x
に対応する公開値y = g^x mod p
。
DHの秘密鍵ファイルはPKCS#8形式またはPKCS#3形式で表現されます。PKCS#3形式ではパラメータ(p, g)と秘密鍵(x)が直接含まれます。
genpkeyでのDH秘密鍵生成:
DH鍵を生成する場合、通常はまずパラメータセットを生成し、そのパラメータセットを使って秘密鍵を生成するという二段階の手順をとります。
-
パラメータ生成:
“`bash
2048ビット長のDHパラメータを生成(素数pの長さ)
openssl genpkey -algorithm DH -genparam -out dhparam_2048.pem -pkeyopt dh_paramgen_prime_len:2048
3072ビット長、生成元g=2のDHパラメータを生成
openssl genpkey -algorithm DH -genparam -out dhparam_3072_g2.pem -pkeyopt dh_paramgen_prime_len:3072 -pkeyopt dh_paramgen_generator:2
RFC 7919 で定義されたffdhe4096グループのパラメータを生成 (OpenSSL 3.0以降)
openssl genpkey -algorithm DH -genparam -out ffdhe4096_param.pem -pkeyopt group:ffdhe4096
“`パラメータ生成には
-genparam
オプションを使用します。-pkeyopt dh_paramgen_prime_len:<bits>
で素数p
のビット長を、-pkeyopt dh_paramgen_generator:<g>
で生成元g
を指定できます。伝統的にはg=2
やg=5
がよく使われます。
OpenSSL 3.0以降では、RFC 7919で定義された標準的な有限体Diffie-Hellman指数グループ(FFDHEグループ)を-pkeyopt group:<group_name>
で指定してパラメータを生成できます。例えばffdhe2048
,ffdhe3072
,ffdhe4096
などです。これらのグループは、既知の良いパラメータセットを提供します。 -
秘密鍵生成(パラメータファイルを使用):
“`bash
生成したDHパラメータファイルを使用して秘密鍵を生成
openssl genpkey -paramfile dhparam_2048.pem -out dh_private_key.pem
パスフレーズで暗号化して生成
openssl genpkey -paramfile dhparam_2048.pem -out encrypted_dh_private_key.pem -aes256 -pass stdin
“`秘密鍵生成時には
-paramfile
オプションでパラメータファイルを指定します。
鍵の用途:
DH鍵は主に鍵交換に使用されます。TLS/SSLのハンドシェイクで一時的な鍵交換(DHE – Ephemeral Diffie-Hellman)を行う際などに利用されます。
セキュリティ上の注意点:
- 使用するパラメータ(p, g)は、十分に大きく、かつ適切に生成されたものであること。パラメータの質はDH鍵交換のセキュリティに直接影響します。大きな素数
p
を見つけることや、生成元g
の選択には注意が必要です(OpenSSLの-genparam
は通常、安全なパラメータを生成します)。既知の良いパラメータセットであるFFDHEグループの使用が推奨されます。 - 素数
p
の長さは、RSA鍵長と同様にセキュリティレベルに影響します。2048ビット以上が推奨されます。 - 秘密鍵ファイルは厳重に管理すること。一時的な鍵交換(DHE)では、秘密鍵はセッション終了後に破棄されるべきです(フォワードシークレットの提供)。
DSA (Digital Signature Algorithm)
DSAは、米国の国家標準として採用されたデジタル署名アルゴリズムです。その安全性は、有限体上の離散対数問題の困難性に基づいています。DSAは署名専用のアルゴリズムであり、暗号化には使用できません。
原理:
DSAは、公開パラメータ (p, q, g)
を使用します。ここで p
は大きな素数、q
は p-1
を割り切る素数、g
は g^q ≡ 1 mod p
となる値です。秘密鍵は 0 < x < q
を満たす整数 x
、公開鍵は y = g^x mod p
です。署名時には秘密鍵 x
を使用し、検証時には公開鍵 y
を使用します。
秘密鍵の構造:
DSA秘密鍵ファイルには、以下の情報が含まれます。
- パラメータ (p, q, g): 鍵で使用されるDSAパラメータ。
- 秘密鍵 (x): 署名に使用する秘密の整数。
- 公開鍵 (y): 検証に使用する公開鍵
y = g^x mod p
。
DSA秘密鍵ファイルはPKCS#8形式またはPKCS#3形式で表現されます。
genpkeyでのDSA秘密鍵生成:
DHと同様に、DSA鍵生成も通常はまずパラメータセットを生成し、そのパラメータセットを使って秘密鍵を生成するという二段階の手順をとります。
-
パラメータ生成:
“`bash
NIST SP 800-57で定義されるL=2048, N=256のDSAパラメータを生成
openssl genpkey -algorithm DSA -genparam -out dsaparam_2048_256.pem -pkeyopt dsa_paramgen_bits:2048 -pkeyopt dsa_paramgen_q_bits:256
L=3072, N=256のDSAパラメータを生成
openssl genpkey -algorithm DSA -genparam -out dsaparam_3072_256.pem -pkeyopt dsa_paramgen_bits:3072 -pkeyopt dsa_paramgen_q_bits:256
“`パラメータ生成には
-genparam
オプションを使用します。-pkeyopt dsa_paramgen_bits:<L>
で素数p
のビット長を、-pkeyopt dsa_paramgen_q_bits:<N>
で素数q
のビット長を指定します。NIST SP 800-57では、セキュリティレベルに応じて Lと Nのペア (2048, 224), (2048, 256), (3072, 256) が推奨されています。OpenSSLはデフォルトでNIST推奨の方法で素数を探索します。 -
秘密鍵生成(パラメータファイルを使用):
“`bash
生成したDSAパラメータファイルを使用して秘密鍵を生成
openssl genpkey -paramfile dsaparam_2048_256.pem -out dsa_private_key.pem
パスフレーズで暗号化して生成
openssl genpkey -paramfile dsaparam_2048_256.pem -out encrypted_dsa_private_key.pem -aes256 -pass stdin
“`秘密鍵生成時には
-paramfile
オプションでパラメータファイルを指定します。
鍵の用途:
DSA鍵はデジタル署名と検証にのみ使用されます。証明書署名、ソフトウェアの署名、電子メールの署名(PGP/GPGなど)などで利用されます。
セキュリティ上の注意点:
- 使用するパラメータ(p, q, g)は、十分に大きく、かつ適切に生成されたものであること。DSAのパラメータ生成はDH以上に複雑であり、自分で生成することは非常に困難です。OpenSSLの
-genparam
を使用するのが一般的です。 - 秘密鍵
x
を生成する際には、十分なランダム性が必要不可欠です。ランダム性が不十分だと、秘密鍵が推測されてしまう脆弱性が生じます。 - DSAはECDSA(楕円曲線DSA)と比較して、同じセキュリティレベルを達成するためにより長い鍵とパラメータが必要になります。また、署名生成に時間がかかる傾向があります。これらの理由から、多くの新しいアプリケーションではECDSAがDSAに取って代わっています。
- 秘密鍵ファイルは厳重に管理すること。
X25519 / X448 (Elliptic Curve Diffie-Hellman)
X25519とX448は、Curve25519およびCurve448と呼ばれる特殊な楕円曲線上で定義されたDiffie-Hellman鍵交換アルゴリズムです。これらはEd25519/Ed448と同様に、実装が容易で、計算が高速、かつサイドチャネル攻撃に対する耐性が高いという特徴を持ちます。特にTLS 1.3でEphemeral ECDH (ECDHE) として広く採用されています。OpenSSL 3.0以降で genpkey
の -algorithm
オプションとして直接サポートされています。
原理:
X25519/X448は、楕円曲線上のスカラー倍算に基づく鍵交換プロトコルです。DH鍵交換と同様に、アリスとボブが共有秘密を確立したい場合、それぞれが秘密のスカラー a
と b
を選び、対応する公開値(曲線上の点)A = a*G
、B = b*G
を計算して交換します(Gは基点)。アリスは受け取った B
に自身の秘密スカラー a
を掛けて a*B = a*(b*G) = (ab)*G
を計算し、ボブは受け取った A
に自身の秘密スカラー b
を掛けて b*A = b*(a*G) = (ab)*G
を計算します。こうして得られた点 (ab)*G
のx座標などが共有秘密として使用されます。Curve25519とCurve448は、特定の数学的性質を持つため、従来のECDHよりも計算効率が良く、実装ミスによる脆弱性が生じにくいとされています。
秘密鍵の構造:
X25519/X448の秘密鍵は、通常以下の情報を含みます。
- 秘密スカラー (d): 鍵所有者のみが知る秘密の整数(Curve25519の場合は32バイト、Curve448の場合は56バイト)。
- 公開点 (Q): 対応する公開点(Curve25519の場合は32バイトのx座標、Curve448の場合は56バイトのx座標)。
秘密鍵ファイルはPKCS#8形式で表現されます。
genpkeyでのX25519/X448秘密鍵生成:
Ed25519/Ed448と同様に、X25519およびX448はアルゴリズム自体に曲線パラメータが含まれているため、パラメータ指定は不要です。
“`bash
X25519秘密鍵を生成
openssl genpkey -algorithm X25519 -out x25519_key.pem
X448秘密鍵を生成
openssl genpkey -algorithm X448 -out x448_key.pem
パスフレーズで暗号化
openssl genpkey -algorithm X25519 -out encrypted_x25519_key.pem -aes256 -pass stdin
“`
鍵の用途:
X25519/X448鍵は主に鍵交換に使用されます。TLS 1.3やSignalプロトコルなど、多くの現代的なプロトコルで利用されています。
セキュリティ上の注意点:
- X25519/X448は、設計上高いセキュリティレベルを提供します。Curve25519は128ビット、Curve448は224ビット相当のセキュリティと見なされます。
- 秘密鍵ファイルは厳重に管理すること。鍵交換のたびに新しい一時的な鍵ペアを生成するのが一般的です(XDHではありませんが、ECDHEと同様)。
SM2
SM2は、中国の国家標準として採用された楕円曲線暗号アルゴリズム群です。ECDSA, ECDH, および特定の暗号化方式を組み合わせたものです。中国国内での電子署名、暗号化、鍵交換などで広く使用されています。OpenSSLがSM2をサポートしているビルドであれば、genpkey
でSM2秘密鍵を生成できます。
原理:
SM2は、特定のパラメータを持つ有限体上の楕円曲線上で定義されます。基本的な数学的原理はECDSAやECDHと同様ですが、使用する曲線パラメータや署名/暗号化/鍵交換の具体的な手続きが異なります。特に、署名アルゴリズムにはユーザーIDを使用する特徴があります。
秘密鍵の構造:
SM2秘密鍵は、EC秘密鍵と同様に、秘密整数、公開鍵点、および使用するSM2曲線パラメータを含みます。SM2曲線は、NIST曲線やBrainpool曲線とは異なるパラメータセットを使用します。
genpkeyでのSM2秘密鍵生成:
SM2鍵を生成するには、-algorithm SM2
を指定し、-pkeyopt
で使用するSM2曲線を指定します。
“`bash
SM2秘密鍵を生成(sm2p256v1曲線を使用)
openssl genpkey -algorithm SM2 -out sm2_key.pem -pkeyopt ec_paramgen_curve:sm2p256v1
パスフレーズで暗号化して生成
openssl genpkey -algorithm SM2 -out encrypted_sm2_key.pem -aes256 -pass stdin -pkeyopt ec_paramgen_curve:sm2p256v1
“`
-pkeyopt ec_paramgen_curve:<curve_name>
で、SM2の標準曲線である sm2p256v1
などを指定します。
鍵の用途:
SM2鍵は、デジタル署名、署名検証、データの暗号化、データの復号、鍵交換など、幅広い用途に使用されます。中国国内の様々なセキュリティアプリケーションやプロトコルで利用が義務付けられている場合があります。
セキュリティ上の注意点:
- 使用するSM2曲線は標準のものを使用すること。
- SM2には、署名生成時にユーザーIDを考慮する独特の手続きがあります。これは鍵生成自体とは直接関係ありませんが、SM2秘密鍵を使用するアプリケーションを開発する際には考慮が必要です。
- 秘密鍵ファイルは厳重に管理すること。
鍵の保護
生成された秘密鍵ファイルは、そのアルゴリズムのセキュリティを破られない限り、その秘密鍵が流出しないことが最も重要です。秘密鍵ファイルが第三者の手に渡った場合、その秘密鍵で暗号化されたデータは復号され、その秘密鍵で作成された署名は偽造される可能性があります。
秘密鍵ファイルを保護する最も一般的な方法は、パスフレーズを使用してファイル自体を暗号化することです。openssl genpkey
コマンドは、鍵生成時に様々な暗号アルゴリズムを使用して秘密鍵を暗号化するオプションを提供します。
“`bash
AES-256で暗号化し、パスフレーズをプロンプトで入力
openssl genpkey -algorithm RSA -out encrypted_rsa_key.pem -aes256 -pass stdin -pkeyopt rsa_keygen_bits:2048
DESede (Triple DES) で暗号化し、パスフレーズを環境変数から取得
openssl genpkey -algorithm EC -out encrypted_ec_key.pem -des3 -pass env:MY_KEY_PASS -pkeyopt ec_paramgen_curve:prime256v1
“`
暗号化アルゴリズムとしては、AES (aes128, aes192, aes256) が推奨されます。DESede (des3) は古いアルゴリズムであり、AESよりも強度が低く、速度も遅いため、互換性の理由がない限り使用すべきではありません。
パスフレーズの指定方法(-pass <arg>
)は重要です。コマンドラインに直接パスフレーズを書く pass:value
形式は、コマンド履歴やプロセスリストからパスフレーズが漏洩する可能性があるため、絶対に避けるべきです。stdin
を使用してプロンプトで入力する方法か、file:<path>
や env:<var>
を使用してファイルや環境変数から読み込む方法がより安全です。ファイルから読み込む場合は、そのファイルのアクセス権限を厳重に設定する必要があります。
パスフレーズで保護された秘密鍵を使用する際には、その都度パスフレーズを入力する必要があります。これは自動化されたシステム(ウェブサーバーなど)で秘密鍵を使用する場合に課題となることがあります。自動化が必要な場合は、以下のいずれかの対策が必要です。
- パスフレーズなしの秘密鍵を使用する(最もリスクが高い)。
- 鍵をロードするプログラムがパスフレーズを安全に取得できる仕組みを用意する(例えば、安全なストレージや鍵管理システムから読み込む)。
- ハードウェアセキュリティモジュール(HSM)を使用して秘密鍵を保護する(秘密鍵はHSM外に出さず、HSM内部で暗号演算を実行する)。
パスフレーズ自体の強度も重要です。推測されにくい、十分な長さと複雑さを持つパスフレーズを選ぶ必要があります。
ファイルシステムレベルでのアクセス権限設定も、秘密鍵ファイルを保護する上で不可欠です。秘密鍵ファイルは、その鍵を使用する必要があるユーザーやプロセス以外からは読み取り不可能に設定すべきです(例: chmod 600 private_key.pem
)。
鍵の管理と運用
秘密鍵を安全に生成したら、その後の管理と運用も適切に行う必要があります。
- 秘密鍵のバックアップ: 秘密鍵は、紛失するとそれに対応する公開鍵や証明書が使用不能になるため、安全な場所にバックアップを取ることが重要です。バックアップファイルも同様にパスフレーズで保護し、物理的に安全な場所に保管すべきです。
- 秘密鍵の破棄: 不要になった秘密鍵は、確実に破棄する必要があります。ファイルを単に削除するだけでは、ディスク上にデータが残る可能性があります。安全な削除ツールや、ディスク全体のワイプなどを使用することを検討してください。
-
公開鍵の抽出: 秘密鍵ファイルから対応する公開鍵を抽出するには、
openssl pkey -pubout
コマンドを使用します。“`bash
秘密鍵ファイルから公開鍵を抽出し、public_key.pemに保存
openssl pkey -in private_key.pem -pubout -out public_key.pem
パスフレーズで暗号化された秘密鍵の場合
openssl pkey -in encrypted_private_key.pem -pubout -out public_key.pem -pass stdin
``
openssl req` コマンドを使用します。
抽出された公開鍵ファイルは、通常PKCS#8形式で表現されます。この公開鍵は、証明書を作成したり、他のユーザーに配布したりするために使用されます。
* **証明書署名要求 (CSR) の作成:** 秘密鍵を用いて、公開鍵と組織情報などを含んだ証明書署名要求(CSR)を作成し、認証局(CA)に送るのが一般的です。CSR作成には“`bash
秘密鍵 key.pem を使用してCSRを生成
openssl req -new -key key.pem -out request.csr -sha256 -subj “/C=JP/ST=Tokyo/L=Chiyoda/O=MyCompany/OU=MyDept/CN=www.example.com”
パスフレーズで暗号化された秘密鍵の場合
openssl req -new -key encrypted_key.pem -out request.csr -sha256 -pass stdin -subj “/C=JP/ST=Tokyo/L=Chiyoda/O=MyCompany/OU=MyDept/CN=www.example.com”
``
genpkey
* **鍵のインポート/エクスポート形式:**が生成する秘密鍵のデフォルト形式はPKCS#8 PEM形式です。古いシステムや特定のアプリケーションでは、PKCS#1 PEM形式(RSAの場合)や、鍵と証明書をセットにしたPKCS#12(.pfx/.p12)形式が必要になる場合があります。OpenSSLの
pkeyコマンドや
pkcs12コマンドを使用して、これらの形式間で変換できます。
openssl pkey -in pkcs8_key.pem -traditional -out pkcs1_key.pem
* PKCS#8 to PKCS#1 (traditional):(RSA鍵の場合)
openssl pkey -in pkcs1_key.pem -out pkcs8_key.pem
* PKCS#1 to PKCS#8:(RSA鍵の場合)
openssl pkcs12 -export -in cert.pem -inkey key.pem -out bundle.p12 -name “My Certificate”`
* PEM key+cert to PKCS#12:
高度なトピック
- PKCS#8形式とPKCS#1形式:
- PKCS#1: RSA秘密鍵のパラメータ(n, e, d, p, q, dp, dq, iq)を直接定義した形式です。
openssl rsa
コマンドなどで伝統的に使用されてきました。PEMエンコードされた場合、ヘッダーは-----BEGIN RSA PRIVATE KEY-----
となります。 - PKCS#8: 任意の秘密鍵アルゴリズムに対応できる汎用的な形式です。PrivateKeyInfoという構造を持ち、アルゴリズム識別子とそのアルゴリズムの秘密鍵パラメータ(オクテット列)を含みます。暗号化パスフレーズで保護された場合、EncryptedPrivateKeyInfo構造を使用します。
openssl genpkey
のデフォルト出力形式です。PEMエンコードされた場合、パスフレーズ保護なしなら-----BEGIN PRIVATE KEY-----
、パスフレーズ保護ありなら-----BEGIN ENCRYPTED PRIVATE KEY-----
となります。
genpkey
の-traditional
オプションは、RSA鍵の場合にPKCS#1形式で出力させるためのものです。他のアルゴリズムでは、そのアルゴリズム固有の伝統的な形式(例えばDSAの場合はPKCS#3 DSA)で出力される可能性があります。特別な理由がない限り、より汎用的でセキュリティ機能(暗号化)も標準化されているPKCS#8形式を使用するのが推奨されます。
- PKCS#1: RSA秘密鍵のパラメータ(n, e, d, p, q, dp, dq, iq)を直接定義した形式です。
- パラメータ生成 (
-genparam
):
DHやDSAのように、鍵生成の前に共通のパラメータセットを生成する必要があるアルゴリズムがあります。これらのパラメータセットは、アルゴリズムの実行環境を定義し、同じパラメータセットを使用する鍵は相互運用可能です。安全なパラメータセットの生成は非常に計算負荷が高く、専門的な知識が必要です。OpenSSLの-genparam
オプションは、これらの複雑なパラメータ生成処理を実行してくれます。
例えばDHの場合、大きな素数p
とその生成元g
のペアを見つける必要があります。DSAの場合はさらに、p-1
の約数である素数q
と、g^q ≡ 1 mod p
となるg
を見つける必要があります。OpenSSLはこれらの要件を満たすパラメータを生成しますが、特に長い鍵長の場合、数分から数時間かかることもあります。一度生成したパラメータは、必要に応じてパラメータファイルとして保存し、複数の秘密鍵生成で再利用できます。 - OpenSSL 3.0の新機能:
OpenSSL 3.0では、プロバイダ(Providers)という新しいアーキテクチャが導入されました。これにより、異なるバックエンドで暗号アルゴリズムを実装できるようになり、ハードウェアアクセラレーションやサードパーティ製の暗号モジュール(HSMなど)との連携が容易になりました。genpkey
コマンドもこの新しいアーキテクチャ上で動作し、プロバイダ経由で様々なアルゴリズムやパラメータ生成機能を利用します。
また、OpenSSL 3.0からEd25519, Ed448, X25519, X448といった新しいアルゴリズムが標準でサポートされるようになり、genpkey
コマンドの-algorithm
オプションで直接指定できるようになりました。DHパラメータに関しても、RFC 7919で定義されたFFDHEグループを-pkeyopt group:<group_name>
で指定して生成できるようになりました。 - 量子コンピュータ時代の暗号アルゴリズム (PQC):
将来的に、十分に強力な量子コンピュータが出現すると、現在の主要な公開鍵暗号アルゴリズム(RSA, ECC, DH, DSAなど)の安全性が脅かされる可能性があります。素因数分解問題や離散対数問題は、量子コンピュータ上のShorのアルゴリズムによって効率的に解かれてしまうと考えられているためです。
この問題に対処するため、量子コンピュータでも効率的に解けない数学問題に基づいた新しい暗号アルゴリズム「耐量子計算機暗号(PQC: Post-Quantum Cryptography)」の研究開発が進められています。NISTなどがPQCアルゴリズムの標準化プロセスを進めており、OpenSSLも将来的にこれらの新しいアルゴリズムをサポートしていく予定です。genpkey
コマンドも、将来的にはこれらのPQCアルゴリズムの鍵生成に対応する可能性があります。現時点では、genpkey
でPQC鍵を生成することはできません。
まとめ
openssl genpkey
コマンドは、現代の公開鍵インフラストラクチャを支える様々な暗号アルゴリズムの秘密鍵を生成するための、強力で柔軟なツールです。RSA、EC(ECDSA, EdDSA, XDH含む)、DH、DSA、SM2といった主要なアルゴリズムに対応しており、鍵長やパラメータ、出力形式、パスフレーズによる保護など、詳細なオプションを制御できます。
この記事で解説したように、各アルゴリズムは異なる数学的原理に基づき、それぞれ秘密鍵の構造や生成方法、そして適した用途が異なります。セキュリティレベル、処理性能、互換性などの要素を考慮して、目的に合ったアルゴリズムと適切な鍵長/パラメータを選択することが重要です。
秘密鍵は、公開鍵暗号システムの根幹であり、その所有者にとって最も重要な秘密情報です。openssl genpkey
を使用して秘密鍵を生成する際には、生成された鍵ファイルのパスフレーズによる暗号化、ファイルシステムレベルでの厳重なアクセス権限設定など、適切な保護対策を講じることが不可欠です。
OpenSSLは継続的に開発が進められており、特にOpenSSL 3.0で導入されたプロバイダアーキテクチャや新しいアルゴリズムのサポートは、将来的な暗号技術の進化にも対応していく基盤となります。genpkey
コマンドは、これらの進化を取り込みつつ、安全な秘密鍵生成のニーズに応え続けていくでしょう。
この記事が、openssl genpkey
で生成できる各種アルゴリズムの秘密鍵について、読者の理解を深め、より安全な鍵管理と運用に役立つことを願います。