この記事はAIによって生成されたコンテンツを含みます。(スクショ、コマンド出力、ログ、トレースなどには含みません)
はじめに
SSLやSSHの暗号アルゴリズム設定をスキャナーで収集する場合、大規模環境やコストに余裕がある企業であれば商用スキャナーを使用することが多いと思いますが、もっと簡単に暗号情報を収集したい、コストをかけず収集したいといったニーズもあるかと思います。
オープンソースであるNmapではNSE(Nmap Script Engine)という機能を使って各種暗号アルゴリズムや暗号鍵の鍵長を収集することが可能です。
当記事では、NmapのNSEを使ったSSL通信、SSL証明書、SSH通信、SSH Hostkeyの暗号情報の収集方法と実行結果をCSVに出力保存する例を紹介します。
実行環境
使用したNmapのバージョンです。
$ nmap --version
Nmap version 7.94SVN ( https://nmap.org )
Platform: x86_64-pc-linux-gnu
Compiled with: liblua-5.4.6 openssl-3.0.13 libssh2-1.11.0 libz-1.3 libpcre2-10.42 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
・Linuxサーバー等にNmapをインストールしてください。Nmapのインストール手順は公開情報も多いため割愛します。
・最新の暗号アルゴリズムを検出できるかはNmapに紐づくOpenSSLのバージョンに依存していることが想定されますので、最新の暗号アルゴリズムを検出したい場合は新しいバージョンのOpenSSLでコンパイルしてみてください。
・CSV整形用のコマンドはLinux用ですので、Windowsの場合はWSLでの利用をお勧めします。
・Nmapサーバーからスキャン対象へのスキャン通信が必要となるのでNW FirewallやOS Firewallでブロックされないことが前提です。
実行結果
SSL通信、SSL証明書、SSH通信、SSH Hostkeyについて実行例やコマンドをそれぞれ紹介します。
・Nmap実行例
・CSV保存コマンド例
・CSV結果例
今回紹介するCSV保存用のコマンドは単一の機器、単一のポート番号を対象にしたコマンドです。
複数の機器、複数のポート番号を一括取得するケースには対応していない点にご注意ください。
複数対象ケースでの一括取得はご自身でコマンドを修正してお試しください。
1. SSL通信
【Nmap実行例】
CSV保存コマンドの元ネタとなるNmap実行例です。
CSV取得不要の場合はこちらのコマンドで調査するのでも良いと思います。
$ nmap -Pn --script ssl-enum-ciphers -p 443 xxx.example.com
<省略>
PORT STATE SERVICE
443/tcp open https
| ssl-enum-ciphers:
| TLSv1.0:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
| compressors:
| NULL
| cipher preference: server
| warnings:
| 64-bit block cipher 3DES vulnerable to SWEET32 attack
| TLSv1.1:
| ciphers:
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| compressors:
| NULL
| cipher preference: server
| TLSv1.2:
| ciphers:
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
| compressors:
| NULL
| cipher preference: client
| TLSv1.3:
| ciphers:
| TLS_AKE_WITH_AES_128_GCM_SHA256 (ecdh_x25519) - A
| TLS_AKE_WITH_AES_256_GCM_SHA384 (ecdh_x25519) - A
| TLS_AKE_WITH_CHACHA20_POLY1305_SHA256 (ecdh_x25519) - A
| cipher preference: client
|_ least strength: C
Nmap done: 1 IP address (1 host up) scanned in 14.30 seconds
【CSV保存コマンド例】
Nmap実行結果を整理しやすいようにCSVファイル化する例です。
スキャン対象に合わせてPORTやTARGETを入力します。
TARGET=xxx.example.com # スキャン対象のFQDN or IPアドレスを指定
PORT=443 # スキャン対象ポートを指定
echo '"Host","Port","TLS_Version","Cipher","Kex"' > ssl_inventory.csv
nmap -Pn --script ssl-enum-ciphers -p ${PORT} ${TARGET} | \
awk -v host="${TARGET}" -v port="${PORT}" '
/^\| TLSv[0-9.]+:/ {
tls=$2
sub(/:/,"",tls)
}
/^\| TLS_/ {
line=$0
match(line,/TLS_[^ ]+/)
cipher=substr(line,RSTART,RLENGTH)
kex=""
if (match(line,/\([^)]*\)/)) {
kex=substr(line,RSTART+1,RLENGTH-2)
}
printf "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n",
host,port,tls,cipher,kex
}
' >> ssl_inventory.csv
上記ではNmap実行結果から「Host」、「Port」、「TLS_Version」、「Cipher」、「Kex」の種類毎に整形したCSVを作成します。
【CSV結果例】
$ cat ssl_inventory.csv
"Host","Port","TLS_Version","Cipher","Kex"
"xxx.example.com","443","TLSv1.0","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.0","TLS_RSA_WITH_AES_128_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.0","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.0","TLS_RSA_WITH_AES_256_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.0","TLS_RSA_WITH_3DES_EDE_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.1","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.1","TLS_RSA_WITH_AES_128_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.1","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.1","TLS_RSA_WITH_AES_256_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_128_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_128_CBC_SHA256","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_128_GCM_SHA256","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_256_CBC_SHA","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_256_CBC_SHA256","rsa 2048"
"xxx.example.com","443","TLSv1.2","TLS_RSA_WITH_AES_256_GCM_SHA384","rsa 2048"
"xxx.example.com","443","TLSv1.3","TLS_AKE_WITH_AES_128_GCM_SHA256","ecdh_x25519"
"xxx.example.com","443","TLSv1.3","TLS_AKE_WITH_AES_256_GCM_SHA384","ecdh_x25519"
"xxx.example.com","443","TLSv1.3","TLS_AKE_WITH_CHACHA20_POLY1305_SHA256","ecdh_x25519"
2. SSL証明書
【Nmap実行例】
CSV保存コマンドの元ネタとなるNmap実行例です。
CSV取得不要の場合はこちらのコマンドで調査するのでも良いと思います。
$ nmap -Pn --script ssl-cert -p 443 xxx.example.com
<省略>
PORT STATE SERVICE
443/tcp open https
| ssl-cert: Subject: commonName=example.com
| Subject Alternative Name: DNS:example.com, DNS:*.example.com
| Issuer: commonName=Cloudflare TLS Issuing ECC CA 3/organizationName=SSL Corporation/countryName=US
| Public Key type: ec
| Public Key bits: 256
| Signature Algorithm: ecdsa-with-SHA256
| Not valid before: 2026-09-26T22:49:11
| Not valid after: 2026-12-25T22:56:35
| MD5: aaaa:bbbb:5b62:7203:9270:95a0:5964:1b98
|_SHA-1: cccc:dddd:e7de:8df1:0033:a2af:48c2:2c2f:6580:a21d
Nmap done: 1 IP address (1 host up) scanned in 13.19 seconds
【CSV保存コマンド例】
Nmap実行結果を整理しやすいようにCSVファイル化する例です。
スキャン対象に合わせてPORTやTARGETを入力します。
TARGET=xxx.example.com # スキャン対象のFQDNまたはIPアドレス
PORT=443 # スキャン対象ポート
(
echo '"Host","Port","SAN","Issuer CN","Issuer Org","Public Key Type","Public Key Size","Signature Algorithm","Not valid before","Not valid after","Validity Days"'
nmap -Pn --script ssl-cert -p "${PORT}" "${TARGET}" 2>/dev/null |
awk -F': ' -v host="${TARGET}" -v port="${PORT}" '
/Subject Alternative Name/ {
san=$2
}
/Issuer/ {
issuer=$2
# Issuer Common Nameを抽出
if (match(issuer, /commonName=[^\/]+/)) {
issuer_cn=substr(issuer, RSTART+11, RLENGTH-11)
} else {
issuer_cn=""
}
# Issuer Organization Nameを抽出
if (match(issuer, /organizationName=[^\/]+/)) {
issuer_org=substr(issuer, RSTART+17, RLENGTH-17)
} else {
issuer_org=""
}
}
/Public Key type/ {
keytype=$2
}
/Public Key bits/ {
keysize=$2
}
/Signature Algorithm/ {
sig=$2
}
/Not valid before/ {
nb=$2
}
/Not valid after/ {
na=$2
}
END {
cmd="date -d \"" nb "\" +%s"
cmd | getline s1
close(cmd)
cmd="date -d \"" na "\" +%s"
cmd | getline s2
close(cmd)
if (s1 != "" && s2 != "") {
validity=int((s2-s1)/86400)
} else {
validity=""
}
# CSV内の二重引用符をエスケープ
gsub(/"/, "\"\"", san)
gsub(/"/, "\"\"", issuer_cn)
gsub(/"/, "\"\"", issuer_org)
printf "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", \
host, port, san, issuer_cn, issuer_org, keytype, keysize, sig, nb, na, validity
}'
) > cert_inventory.csv
上記ではNmap実行結果から「Host」、「Port」、「SAN」、「Issuer CN」、「Issuer Org」、「Public Key Type」、「Public Key Size」、「Signature Algorithm」、「Not valid before」、「Not valid after」、「Validity Days」の種類毎に整形したCSVを作成します。
「Validity Days」は「Not valid before」、「Not valid after」の値から計算した証明書有効期間(日数)を追加しています。
【CSV結果例】
$ cat cert_inventory.csv
"Host","Port","SAN","Issuer CN","Issuer Org","Public Key Type","Public Key Size","Signature Algorithm","Not valid before","Not valid after","Validity Days"
"xxx.example.com","443","DNS:example.com, DNS:*.example.com","Cloudflare TLS Issuing ECC CA 3","SSL Corporation","ec","256","ecdsa-with-SHA256","2026-09-26T22:49:11"," 2026-12-25T22:56:35","90"
3. SSH通信
【Nmap実行例】
CSV保存コマンドの元ネタとなるNmap実行例です。
CSV取得不要の場合はこちらのコマンドで調査するのでも良いと思います。
$ nmap -Pn -p22 --script ssh2-enum-algos -vv 172.22.175.43
<省略>
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack
| ssh2-enum-algos:
| kex_algorithms: (12)
| sntrup761x25519-sha512@openssh.com
| curve25519-sha256
| curve25519-sha256@libssh.org
| ecdh-sha2-nistp256
| ecdh-sha2-nistp384
| ecdh-sha2-nistp521
| diffie-hellman-group-exchange-sha256
| diffie-hellman-group16-sha512
| diffie-hellman-group18-sha512
| diffie-hellman-group14-sha256
| ext-info-s
| kex-strict-s-v00@openssh.com
| server_host_key_algorithms: (4)
| rsa-sha2-512
| rsa-sha2-256
| ecdsa-sha2-nistp256
| ssh-ed25519
| encryption_algorithms: (6)
| chacha20-poly1305@openssh.com
| aes128-ctr
| aes192-ctr
| aes256-ctr
| aes128-gcm@openssh.com
| aes256-gcm@openssh.com
| mac_algorithms: (10)
| umac-64-etm@openssh.com
| umac-128-etm@openssh.com
| hmac-sha2-256-etm@openssh.com
| hmac-sha2-512-etm@openssh.com
| hmac-sha1-etm@openssh.com
| umac-64@openssh.com
| umac-128@openssh.com
| hmac-sha2-256
| hmac-sha2-512
| hmac-sha1
| compression_algorithms: (2)
| none
|_ zlib@openssh.com
NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 17:59
Completed NSE at 17:59, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 13.13 seconds
【CSV保存コマンド例】
Nmap実行結果を整理しやすいようにCSVファイル化する例です。
スキャン対象に合わせてPORTやTARGETを入力します。
TARGET=172.22.175.43 # スキャン対象のIPアドレス or FQDNを指定
PORT=22 # スキャン対象ポートを指定
echo '"Host","Port","KEX","HostKey","Encryption","MAC"' > ssh_cipher_inventory.csv
nmap -Pn -p${PORT} --script ssh2-enum-algos -vv ${TARGET} |
awk -v host="${TARGET}" -v port="${PORT}" '
/kex_algorithms:/ {sec="kex";next}
/server_host_key_algorithms:/ {sec="hostkey";next}
/encryption_algorithms:/ {sec="enc";next}
/mac_algorithms:/ {sec="mac";next}
/compression_algorithms:/ {sec="";next}
(/^[|][[:space:]]+[A-Za-z0-9_-]+:/) {next}
/^[|][[:space:]]+/ {
line=$0
gsub(/^[|][[:space:]]+/,"",line)
gsub(/[[:space:]]+$/,"",line)
if(sec=="kex") {
# SSH拡張情報はCSVに含めない
if(line ~ /^ext-info-/) next
if(line ~ /^kex-strict-/) next
if(kex!="") kex=kex";"line
else kex=line
}
else if(sec=="hostkey") {
if(hostkey!="") hostkey=hostkey";"line
else hostkey=line
}
else if(sec=="enc") {
if(enc!="") enc=enc";"line
else enc=line
}
else if(sec=="mac") {
if(mac!="") mac=mac";"line
else mac=line
}
}
END{
print "\""host"\",\""port"\",\""kex"\",\""hostkey"\",\""enc"\",\""mac"\""
}' >> ssh_cipher_inventory.csv
上記ではNmap実行結果から「Host」、「Port」、「KEX」、「HostKey」、「Encryption」、「MAC」の種類毎に整形したCSVを作成します。
Nmap実行結果のうち、KEXのext-info-s、kex-strict-s-v00@openssh.comは実際に有効化されているアルゴリズムではなくダミーで出力されるものなのでCSVから排除するようにしています。
【CSV結果例】
$ cat ssh_cipher_inventory.csv
"Host","Port","KEX","HostKey","Encryption","MAC"
"172.22.175.43","22","sntrup761x25519-sha512@openssh.com;curve25519-sha256;curve25519-sha256@libssh.org;ecdh-sha2-nistp256;ecdh-sha2-nistp384;ecdh-sha2-nistp521;diffie-hellman-group-exchange-sha256;diffie-hellman-group16-sha512;diffie-hellman-group18-sha512;diffie-hellman-group14-sha256","rsa-sha2-512;rsa-sha2-256;ecdsa-sha2-nistp256;ssh-ed25519","chacha20-poly1305@openssh.com;aes128-ctr;aes192-ctr;aes256-ctr;aes128-gcm@openssh.com;aes256-gcm@openssh.com","umac-64-etm@openssh.com;umac-128-etm@openssh.com;hmac-sha2-256-etm@openssh.com;hmac-sha2-512-etm@openssh.com;hmac-sha1-etm@openssh.com;umac-64@openssh.com;umac-128@openssh.com;hmac-sha2-256;hmac-sha2-512;hmac-sha1"
4. SSH Hostkey
【Nmap実行例】
CSV保存コマンドの元ネタとなるNmap実行例です。
CSV取得不要の場合はこちらのコマンドで調査するのでも良いと思います。
$ nmap -Pn -p22 --script ssh-hostkey 172.22.175.43
<省略>
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey:
| 256 d8:71:a6:8a:b9:d0:55:99:ba:6a:57:76:ef:23:9a:e1 (ECDSA)
|_ 256 20:f1:f0:e9:d4:d2:34:31:14:70:d3:e1:93:65:b9:b1 (ED25519)
Nmap done: 1 IP address (1 host up) scanned in 0.12 seconds
【CSV保存コマンド例】
Nmap実行結果を整理しやすいようにCSVファイル化する例です。
スキャン対象に合わせてPORTやTARGETを入力します。
TARGET=172.22.175.43 # スキャン対象のIPアドレス or FQDNを指定
PORT=22 # スキャン対象ポートを指定
(
echo '"Host","Port","Hostkey","Hostkey size"'
nmap -Pn --script ssh-hostkey -p "${PORT}" "${TARGET}" 2>/dev/null |
awk -v host="${TARGET}" -v port="${PORT}" '
match($0, /[0-9]+ .* \(([A-Za-z0-9-]+)\)$/) {
alg=$NF
gsub(/[()]/,"",alg)
if (match($0, /[0-9]+/))
size=substr($0,RSTART,RLENGTH)
printf "\"%s\",\"%s\",\"%s\",\"%s\"\n", \
host, port, alg, size
}
'
) > ssh_hostkey_inventory.csv
上記ではNmap実行結果から「Host」、「Port」、「HostKey」、「HostKey size」の種類毎に整形したCSVを作成します。
【CSV結果例】
$ cat ssh_hostkey_inventory.csv
"Host","Port","Hostkey","Hostkey size"
"172.22.175.43","22","ECDSA","256"
"172.22.175.43","22","ED25519","256"
まとめ
Nmapを使って暗号アルゴリズム情報を取得しCSV保存する例を紹介しました。
無償のツールでもスキャン対象にアクセスできる環境があれば暗号情報を収集して結果を整理することが可能です。
お試しでクリプト・インベントリーを作成するような機会があれば記事の内容を参考にしてみてください。
参考資料
NSEの内容を理解する際に参考にさせて頂きました。
nmap のイメージが変わった Nmap Scripting Engine (NSE)