从指纹显示密钥的randomart图像的命令?

问题描述 投票:2回答:1

我有一个ssh-key指纹:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48

我想看看这个指纹的randomart图像。

是否有一个命令将此指纹作为输入并输出randomart图像?

PS:我不是要求SSH命令附带的“-o VisualHostKey”选项。

ssh-keys fingerprint
1个回答
3
投票

不会。您提供的只是密钥的(可能是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

Command Synopsis:

ssh-keygen -l [-v] [-E <fingerprint_hash>] [-f <input_keyfile>]
  • -l 指定公钥文件的指纹 随着-v打印指纹和视觉ASCII艺术的关键
  • -E <hash_algorithm> 指定显示关键指纹时使用的哈希算法 有效选项: sha256(默认) md5(较旧的系统仅使用md5)
  • -f <key file> 指定将从中制作指纹的ssh密钥 任何具有有效公钥格式的东西 包括authorized_keysknown_hosts <key file>可能包含私人或公共密钥 公共密钥可以由用户使用-y选项从私钥文件派生 例如ssh-keygen -yf ~/.ssh/id_asghar 手册页:https://linux.die.net/man/1/ssh-keygen

Note:

可以使用ssh-keyscan <host>获取活动ssh服务器的ssh密钥


Command Synopsis:

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 输出中的哈希主机名 安全选项 哈兹可以被sshsshd使用
  • -p <port> ssh服务器端口正在侦听 默认值:22
  • -T <timeout> 在放弃之前等待timeout秒 默认值:5
  • -t 从ssh服务器获取密钥的类型。 用逗号分隔的多个类型 默认值:显示所有可用键 有效选项: rsa1(仅限第1版) rsa dsa ecdsa ed25519
  • -v 详细输出 可以重复几次以根据需要增加详细程度
  • 手册页:https://linux.die.net/man/1/ssh-keyscan

例如获取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()

© www.soinside.com 2019 - 2024. All rights reserved.