我有一个ssh-key指纹:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
我想看看这个指纹的randomart图像。
是否有一个命令将此指纹作为输入并输出randomart图像?
PS:我不是要求SSH命令附带的“-o VisualHostKey”选项。
不会。您提供的只是密钥的(可能是MD5)指纹。 SSH randomart显示加密算法和散列算法以及从指纹创建的视觉艺术。 OpenSSH似乎没有提供从指纹本身生成ASCII视觉艺术的工具,但该指纹是从您可能有权访问的公钥生成的。如果是这种情况,那么您可以将该公钥放在一个文件中并在其上运行ssh-keygen -l
。
对于特定密钥:
ssh-keygen -lvf ~/.ssh/<id_whatever_name>
例如对于known_hosts
中的所有条目(可能没有用但对演示有用)
ssh-keygen -lvf ~/.ssh/known_hosts
对于默认密钥:
ssh-keygen -lv
ssh-keygen -l [-v] [-E <fingerprint_hash>] [-f <input_keyfile>]
-l
指定公钥文件的指纹
随着-v
打印指纹和视觉ASCII艺术的关键-E <hash_algorithm>
指定显示关键指纹时使用的哈希算法
有效选项:
sha256
(默认)
md5
(较旧的系统仅使用md5)-f <key file>
指定将从中制作指纹的ssh密钥
任何具有有效公钥格式的东西
包括authorized_keys
,known_hosts
<key file>
可能包含私人或公共密钥
公共密钥可以由用户使用-y
选项从私钥文件派生
例如ssh-keygen -yf ~/.ssh/id_asghar
手册页:https://linux.die.net/man/1/ssh-keygenNote:
可以使用
ssh-keyscan <host>
获取活动ssh服务器的ssh密钥
ssh-keyscan [-4|-6] [-f -|<file>] [-H] [-p <port>] [-T <timeout>] [-t <key type>] [-v]
-4
仅连接到IPv4主机-6
仅连接到IPv6主机-f
读主机名或<addrlist> <namelist>
对
-f -
从stdin读取
-f <file>
阅读file
格式
<host_address>[,<host_address>...] [<host_name>,[<host_name>...]]
每行一个条目
例如
1.2.3.6
someother.fqdn,1.2.3.7,1.2.3.8```
-H
输出中的哈希主机名
安全选项
哈兹可以被ssh
和sshd
使用-p <port>
ssh服务器端口正在侦听
默认值:22-T <timeout>
在放弃之前等待timeout
秒
默认值:5-t
从ssh服务器获取密钥的类型。
用逗号分隔的多个类型
默认值:显示所有可用键
有效选项:
rsa1
(仅限第1版)
rsa
dsa
ecdsa
ed25519
-v
详细输出
可以重复几次以根据需要增加详细程度例如获取github.com的RSA密钥的指纹和ASCII视觉艺术
ssh-keygen -lv -E md5 -f <(ssh-keyscan -t rsa github.com)
但是,如果你真的坚持只从指纹中获取randomart,你可能必须自己生成它。据我所知,OpenSSH使用Drunken Bishop algorithm从指纹生成ASCII视觉艺术。实现这个算法似乎是微不足道的,如果您的主机具有16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
的MD5指纹,则ASCII视觉艺术是:
+---[ n/a ]----+
| . |
| + . |
| . B . |
| o * + |
| X * S |
| + O o . . |
| . E . o |
| . . o |
| . . |
+------[MD5]------+
这是脚本:
#!/usr/bin/env python
# usage: drunken_bishop.py [-h] [--mode {md5,sha256}] fingerprint
#
# Generate randomart from fingerprint
#
# positional arguments:
# fingerprint
#
# optional arguments:
# -h, --help show this help message and exit
# --mode {md5,sha256}, -m {md5,sha256}
import argparse
import base64
import numpy as np
def get_steps(bits):
bits_grouped = np.array(bits, dtype=np.int8).reshape((-1, 4, 2))
bits_grouped_reordered = np.flip(bits_grouped, axis=1)
return bits_grouped_reordered.reshape((-1, 2))
def drunken_bishop(steps):
positions = np.zeros((9, 17), dtype=np.int8)
current_position = np.array([4, 8])
def move(b0, b1):
if (b0, b1) == (0, 0):
return (-1, -1)
elif (b0, b1) == (0, 1):
return (-1, 1)
elif (b0, b1) == (1, 0):
return (1, -1)
elif (b0, b1) == (1, 1):
return (1, 1)
raise Exception('Impossible move: ({}, {})'.format(b0, b1))
for step in steps:
positions[tuple(current_position)] += 1
current_position += move(step[0], step[1])
if current_position[0] >= positions.shape[0]:
current_position[0] = positions.shape[0] - 1
elif current_position[0] <= 0:
current_position[0] = 0
if current_position[1] >= positions.shape[1]:
current_position[1] = positions.shape[1] - 1
elif current_position[1] <= 0:
current_position[1] = 0
positions[(4, 8)] = 15
positions[tuple(current_position)] = 16
return positions
def print_randomart(atrium):
values = {
0: ' ', 1: '.', 2: 'o', 3: '+', 4: '=', 5: '*', 6: 'B', 7: 'O', 8: 'X',
9: '@', 10: '%', 11: '&', 12: '#', 13: '/', 14: '^', 15: 'S', 16: 'E'
}
print('+---[ n/a ]----+')
for r in atrium:
print('|', end='')
for c in r:
print(values[c], end='')
print('|')
print('+-----------------+')
def get_md5_bits(fingerprint):
return np.array([list('{:08b}'.format(int(i, 16))) for i in fingerprint.split(':')])
def get_sha256_bits(fingerprint):
missing_padding = 4 - (len(fingerprint) % 4)
fingerprint += '=' * missing_padding
return np.array([list('{:08b}'.format(i)) for i in base64.b64decode(fingerprint)])
def main():
parser = argparse.ArgumentParser(
description='Generate randomart from fingerprint')
parser.add_argument('--mode', '-m', choices=['md5', 'sha256'], default='md5')
parser.add_argument('fingerprint', type=str)
args = parser.parse_args()
bits = None;
if args.mode == 'md5':
bits = get_md5_bits(args.fingerprint)
elif args.mode == 'sha256':
bits = get_sha256_bits(args.fingerprint)
else:
raise Exception('Unsupported hashing mode: {}'.format(args.mode))
steps = get_steps(bits)
atrium = drunken_bishop(steps)
print_randomart(atrium)
if __name__ == '__main__':
main()