UNIX/Linuxの部屋 opensslコマンドの使い方

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド openssl 暗号化・復号化・公開鍵などを扱うツール このエントリーをはてなブックマークに追加

最終更新


openssl コマンドは、OpenSSL プロジェクトが開発・配布しているソフトウェアに付属するコマンドで、これを使うと OpenSSL ライブラリのさまざまな機能を使うことができる。FreeBSD・Linux (CentOS 等) など近年の UNIX 系 OS では、ほとんどの環境ですでにインストール済ですぐに使用可能なことが多いだろう。

openssl コマンド単体で多くの機能を提供しているため非常にわかりにくいが (なんでもかんでも詰め込みすぎだ)、基本は
% openssl コマンド [コマンドごとの引数…]
である。


openssl が受け付けるコマンド一覧
openssl が受け付けるコマンドの一覧は以下の通り。

▷ SSL/TLS関連
ca CA を扱う
ciphers SSL/TLS で使用できる暗号スイート一覧を表示する こちら
crl 証明書取消リスト (CRL) を扱う
crl2pkcs7 証明書取消リスト (CRL) を PKCS#7 形式に変換する
s_client SSL/TLS で指定サーバに接続 こちら
s_server SSL/TLS でデータを受け付けるサーバとして動作
s_time SSL/TLS コネクションタイマ
sess_id SSL/TLS セッションデータ管理
ocsp Online Certificate Status Protocol (OCSP: オンライン証明証ステータスプロトコル) に関するサブコマンド。OCSP は証明書が失効していないかを認証局にオンラインで確認するためのプロトコル。

▷ 公開鍵暗号方式関連
genrsa RSA 秘密鍵を生成 こちら
rsa RSA 鍵を表示・変換・操作する こちら
rsautl RSA による暗号化・復号化・署名・検証を行う こちら
ec 楕円曲線暗号に関するサブコマンド
ecparam 楕円曲線暗号における楕円曲線パラメータに関するサブコマンド
gendh Diffie-Hellman パラメータを生成する。gendh は古いため、dhparam を使うこと。
dh Diffie-Hellman パラメータを管理する。dh は古いため、dhparam を使うこと。
dhparam Diffie-Hellman パラメータを生成・管理する
dsa DSA データを扱う
dsaparam DSA パラメータを生成する
gendsa DSA 秘密鍵を生成
genpkey RSA・DSA・DH・EC などのいろいろな秘密鍵を生成。 こちら
pkey RSA・DSA・DH・EC などのいろいろな公開鍵を管理する
pkeyparam RSA・DSA・DH・EC などのいろいろな公開鍵のパラメータを管理する
pkeyutl RSA・DSA・DH・EC などのいろいろな公開鍵方式にて、暗号化・復号化・署名・検証を行う

▷ 公開鍵暗号フォーマット関連
pkcs12 PKCS#12 (電子証明書や秘密鍵の形式) のデータを扱う
pkcs7 PKCS#7 (暗号化や署名を行ったデータの形式) のデータを扱う
pkcs8 PKCS#8 (秘密鍵情報) のデータを扱う
req PKCS#10 (証明書発行要求の形式) のデータを扱う
verify X.509 公開鍵証明書を検証する
x509 X.509 公開鍵証明書を操作する こちら

▷ 秘密鍵暗号関連
enc 共通鍵暗号方式にて暗号化処理を行う こちら

▷ ハッシュ・ダイジェスト関連
dgst メッセージダイジェストを計算 こちら

▷ 素数・乱数
prime 素数判定・素数生成を行う こちら
rand 乱数を生成 こちら

▷ OpenSSL 関連
errstr エラー番号をわかりやすいエラー文字列に変換 こちら
version OpenSSL のバージョンを表示 こちら
engine OpenSSL の engine (プラグイン的なもの) の状態を表示する。engine を経由して、ハードウェアアクセラレータや AWS CloudHSM などの利用が可能になる

▷ S/MIME 関連
cms メール暗号化技術 S/MIME 関連。CMS (Cryptographic Message Syntax) は S/MIME が扱うフォーマット名
smime S/MIME メール処理

▷ その他
asn1parse ASN.1 データを解析・表示する
nseq Netscape 証明書シーケンスを扱う。Netscape 証明書シーケンスとは、おそらくは PKCS 作成前の古い形式のものらしい。nseq を使うことはないだろう。
passwd UNIX パスワードを生成
speed アルゴリズム速度を計測 こちら
spkac Netscape の SPKAC (Signed Public Key And Challenge) ファイルを操作
srp Secure Remote Password (SRP) に関するもの
ts タイムスタンプ (RFC 3161) の取得・検証

-help オプション
openssl -help で、使用可能なコマンドの一覧等を表示できる。
% openssl -help

また、openssl [コマンド] -help で、それぞれのコマンドに対する引数やオプションの解説を表示することができる。コマンドごとに引数やオプションが大きく異なるので、有用である (下記は openssl dgst のヘルプ)。
% openssl dgst -help
unknown option '-help'
options are
-c to output the digest with separating colons
-r to output the digest in coreutils format
-d to output debug info
-hex output as hex dump
(略)
なお、実際は "unknown option '-help'" とあるように、不正オプションとみなされているだけであるが、コマンドごとのヘルプを表示するオプションは存在しないので、世の中の人は "-help" や "--help" などを渡してヘルプを表示しているようである。

OpenSSL で使用可能な共通鍵暗号の一覧
OpenSSL で使用可能な暗号は以下のようにして調べることができる。
% openssl enc --help
...
Cipher Types
-aes-128-cbc               -aes-128-cfb               -aes-128-ecb              
-aes-128-ofb               -aes-192-cbc               -aes-192-cfb              
-aes-192-ecb               -aes-192-ofb               -aes-256-cbc              
-aes-256-cfb               -aes-256-ecb               -aes-256-ofb              
-aes128                    -aes192                    -aes256                   
-bf                        -bf-cbc                    -bf-cfb                   
-bf-ecb                    -bf-ofb                    -blowfish                 
-cast                      -cast-cbc                  -cast5-cbc                
-cast5-cfb                 -cast5-ecb                 -cast5-ofb                
-des                       -des-cbc                   -des-cfb                  
-des-ecb                   -des-ede                   -des-ede-cbc              
-des-ede-cfb               -des-ede-ofb               -des-ede3                 
-des-ede3-cbc              -des-ede3-cfb              -des-ede3-ofb             
-des-ofb                   -des3                      -desx                     
-desx-cbc                  -rc2                       -rc2-40-cbc               
-rc2-64-cbc                -rc2-cbc                   -rc2-cfb                  
-rc2-ecb                   -rc2-ofb                   -rc4                      
-rc4-40                    -rc5                       -rc5-cbc
-rc5-cfb                   -rc5-ecb                   -rc5-ofb
これらは全て共通鍵暗号方式であることに注意すること。

上記の例では、共通鍵暗号方式アルゴリズムとして AES、Blowfish (BF)、CAST、DES、DESX、IDEA、RC2、RC4、RC5 が利用可能であることがわかる。

また、EDE とあるのは Encrypt-Decrypt-Encrypt (暗号化-復号化-暗号化) のことで、2 つまたは 3 つの鍵を使って
暗号化 → 復号化 → 暗号化
を繰り返すことである。鍵を 2つ使う方式は
鍵 A で暗号化 → 鍵 B で復号化 → 鍵 A で暗号化
で、上記の暗号リストでは単に EDE と記述してある。鍵を 3つ使う方式は
鍵 A で暗号化 → 鍵 B で復号化 → 鍵 C で暗号化
となり、上記の暗号リストでは EDE3 となっている。

また、cbc・ede・ofb・ecb などは暗号モードである。下記にて説明する。

CBC・CFB・ECB・OFB などの暗号モードの説明
上記の CBC・CFB・ECB・OFB とは、暗号モードと呼ばれるものである。

CBC・CFB・ECB・OFB はブロック暗号のモードのこと。例えば一度に 4bit のデータを暗号化できる暗号方式があるとしよう (鍵のことではない。暗号化の対象となるデータ長のこと)。ここで 16bit のデータを暗号化するためには、データを 4bit ごとに区切って 4回暗号化を繰り返さないといけない。ある鍵によって 1111 が 1010 に暗号化される場合、もし入力データが全て 1 だったとしたら、
1111 1111 1111 1111 → 1010 1010 1010 1010
となってしまう。これは解読者に「各 4bit が同じデータである」という解読のためのヒントを与えてしまうので、非常にまずい。また、暗号化されたデータの一部を置き換えることで (解読しなくても) 解読後のデータを差し替えることができてしまう。つまり、各ブロックが完全に独立しているのが問題なのである。

上記のような欠点を防ぐために、ブロックの内容が同じであっても、出力結果が同じにならないための工夫がある。その工夫にはいくつかの種類があり、それが CBC・CFB・ECB・OFB である。詳しい説明は省略するが、以下、3 つはおすすめしないモード。
ECB (Electric CodeBook) … 電子符号表モード
CFB (Cipher FeedBack) … 暗号フィードバックモード
OFB (Output FeedBack) … 出力フィードバックモード
そしておすすめなのは、これ。
CBC (Cipher Block Chaining) … 暗号ブロック連鎖モード

ちなみに上記の例では 4bit ブロック暗号方式を例にあげたが、DES は 64bit ブロック暗号、AES は 128・192・256 bit からブロックを選択可能である。

openssl ciphers … SSL/TLS で使用できる暗号スイート一覧を表示する
% openssl ciphers
AES256-SHA:DHE-RSA-AES256-SHA:(略):EXP-RC4-MD5:EXP-RC4-MD5
⇒ この環境の OpenSSL で使用できる SSL/TLS の暗号スイート一覧を表示する。

% openssl ciphers -v
AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
(略)
EXP-RC4-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
EXP-RC4-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
-v オプションを付けることで、それぞれの暗号スイートの意味を少しだけわかりやすく表示してくれる。例えば一行目の「AES256-SHA」は
  • SSLv3 で使用可能
  • 公開鍵暗号方式は RSA
  • 共通鍵暗号方法は AES 256bit
  • ハッシュ関数 SHA1
であることがわかる。

% openssl ciphers [暗号スイートリスト...]
暗号スイートを指定して、使用可能な暗号スイートを表示する。用途としては、Apache の httpd.conf における SSLCipherSuite ディレクティブの内容を確認するとか、SSL/TLS クライアントを作る際の SSL_CTX_set_cipher_list 関数に渡す文字列を確認するなど、マイナーなところで大活躍している。

暗号スイートリストは openssl ciphers で表示される「DHE-RSA-AES256-SHA」のような暗号スイート名に加え、さらに以下のキーワードを使用できる。
DEFAULT デフォルトの暗号スイート。ALL:!ADH:RC4+RSA: +SSLv2:@STRENGTH と同じ
ALL 使用可能な全ての暗号スイート。ただし eNULL を除く。
COMPLEMENT OFDEFAULT ALL に含まれるが DEFALUT には含まれない暗号スイート
COMPLEMENT OFALL 使用可能であるが ALL に含まれない暗号スイート。つまり eNULL
HIGH 共通鍵暗号方式の鍵長が 128bit より大きい暗号スイート
MEDIUM 共通鍵暗号方式の鍵長が 128bit の暗号スイート
LOW 共通鍵暗号方式の鍵長が 56bit または 64bit の暗号スイート
EXP, EXPORT 米国外に輸出可能な暗号スイート
EXPORT40 米国外に輸出可能で共通鍵暗号方式の鍵長が 40bit の暗号スイート
EXPORT56 米国外に輸出可能で共通鍵暗号方式の鍵長が 56bit の暗号スイート
AES 共通鍵暗号方式に AES を使った暗号スイート
3DES 共通鍵暗号方式に 3DES を使った暗号スイート
DES 共通鍵暗号方式に DES を使った暗号スイート
RC4 共通鍵暗号方式に RC4 を使った暗号スイート
RC2 共通鍵暗号方式に RC2 を使った暗号スイート
IDEA 共通鍵暗号方式に IDEA を使った暗号スイート
MD5 ハッシュアルゴリズムに MD5 を使った暗号スイート
SHA1, SHA ハッシュアルゴリズムに SHA1 を使った暗号スイート
ADH 認証に 匿名 DH (Anonymous Diffie-Hellman) を使った暗号スイート
DH 認証に DH (Diffie-Hellman) を使った暗号スイート。ADH を含む

暗号スイートやキーワードはコロンでつなぐことで複数指定することができる。
% openssl ciphers AES256-SHA:MD5
AES256-SHA:(略):EXP-RC4-MD5
⇒ AES256-SHA と、ハッシュアルゴリズムに MD5 を使った暗号スイート

もしタイプミスをしていたり、コンパイルオプションなどで特定の暗号が使用できない状況になっていた場合は、以下のように暗号スイートが表示されない。
% openssl ciphers AES256-SHA:MD5
⇒ 何も表示されない。この環境では適合する暗号スイートがないということ

暗号スイートやキーワードは「A+B」とすることで AND 条件を取ることができる。
% openssl ciphers AES+SHA
⇒ 共通鍵暗号方式に AES を使い、なおかつハッシュアルゴリズムに SHA1 を使う暗号スイート
% openssl ciphers AES:SHA
⇒ コロンで結ぶと「共通鍵暗号方式に AES を使う暗号スイートと、ハッシュアルゴリズムに SHA1 を使う暗号スイートを並べたもの」となってしまうことに注意

文字列の先頭に `-' を付けることで、その暗号スイートを削除することができる。
% openssl ciphers ALL:-RC4
⇒ 全ての暗号スイートから RC4 が関係するものを除いたもの
% openssl ciphers ALL:-RC4:MD5
⇒ 全ての暗号スイートから RC4 が関係するものを除き、さらに MD5 に関係するものを加える。一度 `-' で取り除いたものを後から加えることも可能なため、最終的に暗号スイート「RC4-MD5」は表示される。

一度取り除いた暗号スイートを二度と追加させないようにするには、`!' を使う。
% openssl ciphers ALL:\!RC4:MD5
⇒ 全ての暗号スイートから RC4 が関係するものを除き、さらに MD5 に関係するものを加える (このとき RC4 に関係する暗号スイートは追加されない)。最終的に暗号スイート「RC4-MD5」は表示されない。

`+' を使うと、暗号スイートを右側に移動させることができる。つまり削除はしないまでも優先度を下げる効果がある。これは暗号スイートの追加ではなく、ただの移動であることに注意。暗号スイートの追加は「FOO:BAR」などとコロンで結ぶだけでよい。
% openssl ciphers ALL:+LOW
⇒ 全ての暗号スイートから LOW にマッチするものを右側に移動
`+' には「+LOW」 などの優先度を下げる使い方と、「AES+SHA」などのキーワードの AND 条件を取る使い方があることに注意しよう。

@STRENGTH を使うことで暗号強度の強い順にソートできる。
% openssl ciphers AES:SHA1:@STRENGTH
⇒ AES が関係する暗号スイートと SHA1 が関係する暗号スイートを、暗号強度順にソート
% openssl ciphers AES:SHA1:@STRENGTH:+RSA
⇒ AES が関係する暗号スイートと SHA1 が関係する暗号スイートを、暗号強度順にソートし、その後に RSA が関係する暗号スイートの優先度を下げる

openssl dgst … メッセージダイジェストを計算する
% echo -n hoge | openssl dgst -md5
ea703e7aa1efda0064eaa507d9e8ab7e
⇒ 文字列 hoge の MD5 値を表示
% openssl dgst -sha1 file.txt
31f30ddbcb1bf8446576f0e64aa4c88a9f055e3c
⇒ ファイル file.txt の SHA1 値を表示
使用できるメッセージダイジェスト関数は、OpenSSL 1.0.2 では以下の通り。
-md4 -md5 -mdc2 -sha -sha1 -sha224 -sha256 -sha384 -sha512 -mdc2 -ripemd160 -whirlpool

MD5 については FreeBSD など *BSD 系では md5 コマンド、Linux では md5sum コマンドで同じことが実現できる。

openssl enc … 共通鍵暗号方式で暗号化・復号化
openssl enc コマンドは、共通暗号方式でデータを暗号化または復号化する。

plain.txt を AES 128bit で暗号化し、crypted.dat に出力する。
% openssl enc -e -aes128 -in plain.txt -out crypted.dat
enter aes-128-cbc encryption password: (パスワードを入力)
Verifying - enter aes-128-cbc encryption password: (再度パスワードを入力)
crypted.dat を plain2.txt に復号化する (これで plain.txt と plain2.txt は一致するはず)。
% openssl enc -d -aes128 -in crypted.dat -out plain2.txt
enter aes-128-cbc decryption password: (パスワードを入力)

パスワードを手入力したくない場合は、以下のような方法がある。
▷ ファイルからパスワードを読む例 (-pass file:[ファイル名])
% echo hoge > enc_pass.txt
% openssl enc -e -aes128 -in plain.txt -out crypted.dat -pass file:enc_pass.txt
▷ 環境変数からパスワードを読む例 (-pass env:[環境変数名])
% setenv ENC_PASS hoge
→ csh・tcsh の場合
% export ENC_PASS=hoge
→ sh・bash の場合
% openssl enc -e -aes128 -in plain.txt -out crypted.dat -pass env:ENC_PASS
▷ コマンドラインからパスワードを指定 (-pass pass:[パスワード])
% openssl enc -e -aes128 -in plain.txt -out crypted.dat -pass pass:hoge

openssl enc では、Base64 エンコード・デコードも可能。
% echo -n abcdefg | openssl enc -e -base64
YWJjZGVmZw==
⇒ abcdefg を Base64 にエンコード
% echo YWJjZGVmZw== | openssl enc -d -base64
abcdefg
⇒ YWJjZGVmZw== を Base64 デコードして abcdefg に戻す
注意点として、base64 デコード時には末尾に改行を含めないといけないようだ。
% echo -n YWJjZGVmZw== | openssl enc -d -base64
→ echo -n で改行なしにすると何も出力されない

openssl enc で使用可能な共通鍵暗号方式は、下記で確認できる。
% openssl list-cipher-algorithms

openssl errstr … エラー番号をわかりやすいエラー文字列に変換 【2018-12-19追加】
エラーメッセージやログなどに、下記のような出力がされている場合がある。これは OpenSSL のエラーを表すが、番号だけなので全く意味がわからない。
error:0406C06E:lib(4):func(108):reason(110)
このようなときに openssl errstr を使うと、若干わかりやすいエラーメッセージを得ることができる。
openssl errstr 0406C06E
error:0406C06E:rsa routines:RSA_padding_add_PKCS1_type_1:data too large for key size

openssl genpkey … RSA・DSH・DH・EC などのいろいろな秘密鍵を生成 【2018-12-19追加】
openssl genpkey は、RSA・DSH・DH・EC などのいろいろな秘密鍵を生成するサブコマンドである。

当ページ管理人の推測ではあるが、暗号方式・鍵交換方式が出てくるたびに genrsa・gendsa・gendh などのサブコマンドが増えていくのを嫌って、genpkey という汎用的なサブコマンドを用意したのではなかろうか。

RSA 秘密鍵を生成
% openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out genpkey-rsa.key
DSA 鍵(?)を生成
% openssl genpkey -genparam -algorithm dsa -pkeyopt dsa_paramgen_bits:2048 -out genpkey-dsa.key
DH 鍵(?)を生成
% openssl genpkey -genparam -algorithm DH -out dhp.pem -pkeyopt dh_paramgen_prime_len:1024

openssl genrsa … RSA 秘密鍵を生成
基礎知識として、できれば下記を読んでいただきたい。

% openssl genrsa -out private-key.pem 2048
2048bit の秘密鍵を生成し、ファイル private-key.pem に出力する。RSA における秘密鍵は OpenSSL によって自動生成されることに注意しよう。ユーザがパスワードやパスフレーズの入力をするのではない。ファイルの内容は以下のようなものになる。
-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBALZGuIEVleemeQK1Tbl/NamcR3lVEAjikK8op0wQ6yqAtXdo7DiC
Ym06guFtMPbqcBRRvSoCdz5xpYgwj8IeqVUCAwEAAQJAPzIx0f9r487h8cBuXDvw
nQej+Ds3vfzfcPtFVaggALHdZ6Y2Vvh5OgalFkvuawI1r7Watq4a5/QyZehDYWhV
QQIhANwoIen1QeoTGYVlwOI7sXhEHlf1EFRgFuQaqjNzyG6dAiEA0/PGNYMxJTLm
ZCgKcX1REhxH6xiW/nRHNx4iAW7mjBkCIQCmKqBWTqf+fYYAumlYGAf+JyPj7XLy
zEfayQl3pkc8vQIhAMAzoZxJObnH7JEKll3QDEJmDvmsNNDOVP4wfxnZnYuRAiEA
qHBG2F18IA1oJbpcnw31nm5xfwHtRUv/zvX4KRbCdfg=
-----END RSA PRIVATE KEY-----
このファイルは絶対に公開してはいけない。作成直後に
% chmod 400 private-key.pem
とパーミッションを落としておくことを推奨する。

% openssl genrsa -out private-key-crypted-aes256.pem -aes256 2048
Enter pass phrase for private-key-crypted-aes256.pem:
→ パスフレーズ入力を求められているので、自分で決めたパスフレーズを入力する
Verifying - Enter pass phrase for private-key-crypted-aes256.pem:
→ 上記で入力したパスフレーズをもう一度入力
2048bit 秘密鍵を生成した上で、AES 256bit で暗号化する (その際のパスフレーズを入力する)。上で述べたとおり、RSA における秘密鍵は openssl コマンドが勝手に決めるものである。ここで入力するパスフレーズは、AES の鍵であり、RSA の秘密鍵とは何の関係もない。

RSA において秘密鍵がばれるというのは全ての暗号が解読可能になるという重大な事態につながる。よって、秘密鍵をファイルにそのまま保存しておくのはあまりよろしくない。そこで RSA の秘密鍵を共通鍵暗号の AES で暗号化しておくのである。

出力は以下のようなものになる。
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,C0714916A3315F5F1F1A6BE431F1BF07

NtWrAcXY8KU9ze/RfZf/tkouDhEh4dB4ECG0BABSSTVlckcYaH2Y3cuHnDXCoPvk
FyRa79eMV8oGdavmQl51L0GIPLMcv/O0OSRihQPYz01WFaMOncOqoZoTwwVZsWWT
v8kJq/dVlBmjEdXACpIpyKIRxTmU3agp9gdRQ+oGstI8kUgk3E6zqE+pJ6C96Y/Y
5lRKZnNigV1wv5GpvCLnVWTBqIh9Jc8odB4j3gaFKkuYkHx7laqqsyS2ObNbxxKi
nkunGJwit+KH3eRUgzh10Yw+FWzVs26ONj3uAcEWLqs5BfaRyJK/0/Ben1AZOeYA
o2TnvefrFZjlvln5jc8Drct51QeVAmrJKMQprgMZPwtacPRUtOAfJq0JDwne8scu
ys8VFiXA/G9f1UCbxjfyNSTStv+Z/dtMaqpra93zDDo=
-----END RSA PRIVATE KEY-----

RSA の秘密鍵をファイルにそのまま保存するか、暗号化して保存するかは、純粋に運用の問題である。例えば、apache などの web サーバに SSL/TLS を組み込む場合、RSA の秘密鍵を AES などで暗号化して保存しておくと、サーバを起動するたびに人間がパスフレーズを入力する必要がある。このような場合は、安全性が低くなることを承知の上で、RSA の秘密鍵を AES などで暗号化せずにそのまま保存しておく、という選択肢もある。

AES 128 以外にも以下の共通鍵暗号方式が使用できる。
-des … DES (鍵長 56ビット) で暗号化
-des3 … 3DES (Triple-DES。鍵長 112ビット) で暗号化
-aes128 … AES 鍵長 128ビットで暗号化
-aes192 … AES 鍵長 192ビットで暗号化
-aes256 … AES 鍵長 256ビットで暗号化
おすすめするのは当然ながら -aes256 である。

上記の例では引数に 2048 を指定したため、RSA 鍵長は 2048bit となる。古来より openssl genrsa のデフォルトは 1024bit であったのだが、(多分) NIST (米国標準技術研究所: National Institute of Standards and Technology) が米国の政府調達における指針として RSA 1024bit は不可としたため、2009〜2010年頃より世の中の認証局 (ベリサインなど) は次々と 1024bit の鍵の受付を停止した。2017年現在では 2048bit を使用する場合が多いだろう。ちなみに 4096bit や 8192bit も使えなくはないが、認証局により 2048bit のみ受付しているところや 8192bit まで対応しているところなどいろいろである。

ちなみにビット数が増えれば増えるほど、genrsa の時間もかかる。あるサーバでの実行時間を以下に示す。
  • openssl genrsa 1024: 0.085秒
  • openssl genrsa 2048: 0.173秒
  • openssl genrsa 4096: 0.722秒
  • openssl genrsa 8192: 31.59秒
  • openssl genrsa 16384: 8分29秒

なお、RSA の鍵長は 2のべき乗といった制限はないため、例えば 1234bit といった変わった長さの鍵生成も可能である。

生成時に共通鍵暗号方式で暗号化しなかった鍵を暗号化したり、一度暗号化した鍵を復号化するには openssl rsa を使用する。

openssl prime … 素数判定・素数生成を行う
10進数の数値が素数かどうかを判定:
% openssl prime 2305843009213693951
1FFFFFFFFFFFFFFF is prime
→ 引数で指定した数は素数である
% openssl prime 2305843009213693953
2000000000000001 is not prime
→ 引数で指定した数は素数ではない
16進数表記の素数判定は -hex オプションをつける。
% openssl prime -hex E338B9
E338B9 is not prime
openssl rsa … RSA 鍵を表示・変換する
openssl rsa は、RSA の鍵を読み込み、出力するコマンドである。その際、さまざまなオプションをつけることで、
  • 鍵の内容の表示・確認
  • フォーマットの変換 (PEM・DER など)
  • 秘密鍵から公開鍵の生成
  • AES 等共通鍵暗号による暗号化
を行うことができる。

RSA 秘密鍵の内容を表示:
% openssl rsa -in private-key.pem -text
Private-Key: (512 bit)
modulus:
00:cf:d7:b2:2b:f2:3b:ce:92:58:0e:63:0e:40:a9:(略)
publicExponent: 65537 (0x10001)
privateExponent:
00:85:23:39:79:d7:30:a2:71:b2:40:7d:09:7b:38:(略)
prime1:
00:f2:02:fe:b2:24:ee:f6:01:8e:64:24:2f:dd:29:(略)
prime2:
00:db:db:1b:36:51:2e:e3:88:39:93:bd:dd:85:4d:(略)
exponent1:
00:86:e6:5a:78:8c:93:d2:f7:0d:1b:0e:fc:cb:27:(略)
exponent2:
00:91:58:52:af:20:10:7d:7f:8b:80:ee:9e:4a:08:(略)
coefficient:
00:d9:42:f6:06:fb:3a:10:80:08:e6:db:0e:6c:18:(略)
writing RSA key
(略)
秘密鍵には RSA 鍵の全ての情報が含まれていることに注意しよう。よって秘密鍵を公開してしまうと全てがおしまいなわけである。それぞれの数の意味は以下の通り。
  • modules: RSA 構造体の n に相当 (p*q)
  • publicExponent: RSA 構造体の e に相当
  • privateExponent: RSA 構造体の d に相当
  • prime1: RSA 構造体の p に相当 (素数)
  • prime2: RSA 構造体の q に相当 (素数)
  • exponent1: RSA 構造体の dmp1 に相当 (d mod (p-1))
  • exponent2: RSA 構造体の dmq1 に相当 (d mod (q-1))
  • cofficient: RSA 構造体の iqmp に相当 ((q-1) mod p)
解説は
を参照。

RSA 秘密鍵から、RSA 公開鍵を生成:
% openssl rsa -in private-key.pem -pubout -out public-key.pem
出力される公開鍵の内容は以下のようになる。
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALMM4iQMJAFwCkTD927ioG9jhJ0S6Wzj
Vc6QEgJIBbTLSs204VPyr78k8CFZNWQSM8ji0jgJXF8v/1OdkH/TaUUCAwEAAQ==
-----END PUBLIC KEY-----

RSA 公開鍵の内容を表示:
% openssl rsa -in public-key.pem -pubin -text
Modulus (512 bit):
00:cf:d7:b2:2b:f2:3b:ce:92:58:0e:63:0e:40:a9:(略)
Exponent: 65537 (0x10001)
writing RSA key
(略)
⇒ このように公開鍵には e と n しか含まれていない。よって、公開しても問題はない。

RSA 秘密鍵を共通鍵暗号で暗号化:
% openssl rsa -in private.key -aes256 -out private-key-crypted-aes256.pem
共通鍵暗号で暗号化された RSA 秘密鍵を復号化:
% openssl rsa -in private-key-crypted-aes256.pem -out private.key

openssl rsautl … RSA による暗号化・復号化・署名・検証を行う
公開鍵による暗号化:
% openssl rsautl -pubin -inkey public-key.pem -in plain.txt -encrypt -out encrypted.dat
秘密鍵による復号化:
% openssl rsautl -inkey private-key.pem -in encrypted.dat -decrypt -out plain2.txt

openssl x509 … X.509 公開鍵証明書を操作する
証明書の内容を表示:
% openssl x509 -inform pem -in cert.pem -text
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 0 (0x0)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=AU, ST=Queensland, O=CryptSoft Pty Ltd, CN=Server test cert (512 bit)
Validity
Not Before: Sep 9 03:41:26 1997 GMT
Not After : Oct 9 03:41:26 1997 GMT
Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=Eric the Young
Subject Public Key Info:
Public Key Algorithm: dsaEncryption-old
DSA Public Key:
pub:
00:b5:44:a8:f3:83:9e:92:38:ad:28:65:63:c4:bb:(略)
Signature Algorithm: md5WithRSAEncryption
94:e5:24:a0:6a:92:52:75:15:c9:a1:7f:82:a4:2b:c5:cb:e2:(略)
PEM 形式を DER 形式に変換:
% openssl x509 -inform pem -outform der -in cert.pem -out cert.der
DER 形式を PEM 形式に変換:
% openssl x509 -inform der -outform pem -in cert.der -out cert.pem

openssl s_client … SSL/TLS で指定サーバに接続する
https://www.verisign.co.jp/ に接続し、
GET / HTTP/1.0
Host: www.verisign.co.jp
を送信する例。
% openssl s_client -connect www.verisign.co.jp:443
depth=2 /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
verify error:num=19:self signed certificate in certificate chain
verify return:0
(略)
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 1024 bit
SSL-Session:
Protocol : SSLv3
Cipher : RC4-MD5
Session-ID: 5ED79B96790B5EEA2A35EC8343C9B9556ABEF2B467C8FD223ED7FE22F22D2DFF
Session-ID-ctx:
Master-Key: 7AEFB360BFB35D62BE141F13813723E99762B79A6A21FFF1C7D2E3D08773DEDCF668BBDE549172183E199A222B121400
Key-Arg : None
Start Time: 1068629748
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate chain)
---
GET / HTTP/1.0 (★入力待ちになるので、HTTP リクエストをタイプし、Enter)
Host: www.verisign.co.jp (★Enter)
(★もう一度 Enter。すると、下記のようなレスポンスが返ってくる)
HTTP/1.1 200 OK
Date: Mon, 17 Nov 2003 20:37:45 GMT
Vary: Accept-language
Content-type: text/html
Connection: close
(略)

HTTP リクエストを送信する必要はなく、SSL/TLS のやりとりのみ確認したい場合は、標準入力を /dev/null で閉じてやればよい。
% openssl s_client -connect www.verisign.co.jp:443 < /dev/null
(略)

逆に、SSL/TLS は省略し、HTTP リクエスト・レスポンスを中心に見たい場合は、-quiet オプションをつけることで、表示が簡略化される。
% openssl s_client -connect www.verisign.co.jp:443 -quiet
depth=2 C = US, O = "VeriSign, Inc.", (略)
verify return:1
depth=1 C = US, O = Symantec Corporation, OU = Symantec Trust Network, (略)
verify return:1
depth=0 1.3.6.1.4.1.311.60.2.1.3 = US, 1.3.6.1.4.1.311.60.2.1.2 = Delaware, (略)
verify return:1
(ここから HTTP リクエストを入力すればよい)

サーバ側で SNI (Server Name Indication) を使っている場合は、-servername で目的の FQDN を指定する。
% openssl s_client -connect www.verisign.co.jp:443 -servername www.verisin.co.jp
なお、SNI とは、旧来の「IPアドレス1つにつき、SSL 証明書は1つしか扱えない」という制限を解消するために考案された SSL/TLS の拡張である。ちなみに似た目的のもとして SAN (Subject Alternate Names) というものもあるが、
  • SNI は、複数の証明書を 1つの IP アドレスで扱う仕組み
  • SAN は、1枚の証明書内に別名を付与する仕組み
であり、-servername オプションは SNI に対応したサーバに、
「私はこの FQDN に接続しようとしている」
ということを伝えるためのものである。

認証局の証明書を指定する場合、ファイル ca.crt を配置した上で、下記のように -CAfile オプションで指定する。
% openssl s_client -connect www.verisign.co.jp:443 -CAfile ca.crt

SSL/TLS プロトコルのバージョンを制限したい場合、下記を使う。
  • -ssl2 … SSLv2 のみを使って接続する
  • -ssl3 … SSLv3 のみを使って接続する
  • -tls1 … TLS 1.0 のみを使って接続する
  • -tls1_1 … TLS 1.1 のみを使って接続する
  • -tls1_2 … TLS 1.2 のみを使って接続する
  • -tls1_3 … TLS 1.3 のみを使って接続する
  • -dtls1 … DTLS 1.0 のみを使って接続する (DTLS は UDP でのセキュアな接続)
  • -dtls1_2 … DTLS 1.2 のみを使って接続する
SSLv3 を使って接続する例は下記。このサーバは現在使用が推奨されていない SSLv2・SSLv3 には対応していないようなので、接続することができない。
% openssl s_client -connect www.verisign.co.jp:443 -ssl3
(略)
no peer certificate available
(略)

逆に、特定プロトコルを使わないようにしたい場合、下記を使う。
  • -no_ssl2 … SSLv2 を使用せずに接続する
  • -no_ssl3 … SSLv3 を使用せずに接続する
  • -no_tls1 … TLS 1.0 を使用せずに接続する
  • -no_tls1_1 … TLS 1.1 を使用せずに接続する
  • -no_tls1_2 … TLS 1.2 を使用せずに接続する
  • -no_tls1_3 … TLS 1.3 を使用せずに接続する
-ssl2・-ssl3 などと異なり、-no_* は複数指定することができる。
% openssl s_client -connect www.verisign.co.jp:443 -no_ssl2 -no_ssl3
(略)
SSL-Session:
Protocol : TLSv1.2
(略)
→ この例では TLS 1.2 で接続したようだ

openssl speed … アルゴリズム速度を計測する
例えば DES (CBC)、DES-EDE3 (3DES。鍵 3つ)、AES の速度を計測してみよう。
% openssl speed des des-ede3 aes
(略)
Doing des cbc for 3s on 16 size blocks: 1978236 des cbc's in 2.96s
Doing des cbc for 3s on 64 size blocks: 519648 des cbc's in 2.99s
Doing des cbc for 3s on 256 size blocks: 131591 des cbc's in 3.00s
Doing des cbc for 3s on 1024 size blocks: 32823 des cbc's in 2.98s
Doing des cbc for 3s on 8192 size blocks: 4129 des cbc's in 3.00s
(略)
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
des cbc          10694.31k    11124.45k    11238.52k    11264.12k    11280.94k
des ede3          4114.52k     4174.61k     4195.20k     4208.62k     4212.41k
aes-128 cbc      14623.16k    15035.19k    15213.69k    15248.49k    15250.12k
aes-192 cbc      12625.59k    12986.96k    13248.40k    13200.37k    13245.66k
aes-256 cbc      11204.07k    11453.80k    11569.18k    11590.68k    11598.09k

1行目は、DES による暗号化を 16バイトのデータに対して 3秒間実行したところ、1978236 回実行できたことを表す。最後に表示される表を見ると、AES 128 ビットが最速で、DES と AES 256 ビットがほぼ同じ速度、DED-EDE3 (3DES) は DES の 3倍近く遅いことがわかる。

openssl rand … ランダムデータを生成する
100 バイトのランダムデータを生成し、file に出力:
% openssl rand 100 > file
10バイトのランダムデータを生成し、16進数文字列として出力:
% openssl rand -hex 10
dad81005165c675b498e
10バイトのランダムデータを生成し、BASE64 化して出力:
% openssl rand -base64 10
uEKHyWtH/cn13Q==

file にはバイナリデータが格納される。バイナリデータではなく、ランダムな文字列の数値を得たい場合は jot を使うとよい。
他にも、いろいろなランダム・乱数の生成方法を下記にまとめているので、一読いただきたい。

openssl version … openssl コマンドのバージョンを出力する
openssl version で、その環境の openssl のバージョンを出力することができる。-version や --version ではなく version であることに注意。
% openssl version
OpenSSL 1.0.1e-fips 11 Feb 2013
openssl version に -a オプションをつけると、より詳細な情報を出力する。

▷ FreeBSD での openssl version -a の例:
% openssl version -a
OpenSSL 1.0.2j-freebsd 26 Sep 2016
built on: date not available
platform: FreeBSD-amd64
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: clang
OPENSSLDIR: "/etc/ssl"

▷ Linux (CentOS) での openssl version -a の例:
OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Tue Sep 27 12:27:19 UTC 2016
platform: linux-x86_64
options: bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC (略)
OPENSSLDIR: "/etc/pki/tls"
engines: dynamic

Tips1. SSL/TLS 証明書の有効期限確認 2017/08/22 作成
リモートの SSL/TLS 証明書を有効期限を確認したい場合は、openssl s_client と openssl x509 を組み合わせる。servername オプションは SNI のためのものである。s_client の項を参照してほしい。
% openssl s_client -connect www.microsoft.com:443 -servername www.microsoft.com < /dev/null | openssl x509 -text | grep Not
Not Before: Apr 7 00:00:00 2017 GMT
Not After : Apr 8 23:59:59 2019 GMT
→ この例では、2017/04/07 00:00:00 (GMT) 〜2019/04/08 23:59:59 (GMT) の間は有効であることがわかる。
関連コマンド