Comment générer randomart de anyfile?

9

Nous connaissons tous le randomart ASCII généré ssh-keygenlors de la création ou de la validation sshdes clés publiques.

Nous savons également que vous pouvez générer des hachages de n'importe quel fichier avec sha1sumou md5sum.

Mais, est-il possible de générer un style aléatoire "ssh-keygen-style" à partir de n'importe quel fichier qui n'est pas une clé publique ssh?

Ce serait une façon plus amusante de comparer visuellement la somme de contrôle de deux fichiers.

Tulains Córdova
la source

Réponses:

8

Vous pouvez générer un art aléatoire de n'importe quel fichier avec ce petit programme C créé par nirejan :

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

#define XLIM 17
#define YLIM 9
#define ARSZ (XLIM * YLIM)

#define DEBUG 0

static uint16_t array[ARSZ];

const char symbols[] = {
    ' ', '.', 'o', '+',
    '=', '*', 'B', 'O',
    'X', '@', '%', '&',
    '#', '/', '^', 'S', 'E'
};

void print_graph(void)
{
    uint8_t i;
    uint8_t j;
    uint16_t temp;

    printf("+--[ RandomArt ]--+\n");

    for (i = 0; i < YLIM; i++) {
        printf("|");
        for (j = 0; j < XLIM; j++) {
            temp = array[j + XLIM * i];
            printf("%c", symbols[temp]);
        }
        printf("|\n");
    }

    printf("+-----------------+\n");
}

static char string[256];

static int ishex (char c)
{
    if ((c >= '0' && c <= '9') ||
        (c >= 'A' && c <= 'F') ||
        (c >= 'a' && c <= 'f')) {
            return 1;
    }

    return 0;
}

/*
 * The hexval function expects a hexadecimal character in the range
 * [0-9], [A-F] or [a-f]. Passing any other character will result in
 * undefined behaviour. Make sure you validate the character first.
 */
static uint8_t hexval (char c)
{
    if (c <= '9') {
        return (c - '0');
    } else if (c <= 'F') {
        return (c - 'A' + 10);
    } else if (c <= 'f') {
        return (c - 'a' + 10);
    }

    return 0;
}

int convert_string(char *arg)
{
    uint16_t i;
    char c;

    i = 0;
    while (*arg && i < 255) {
        c = *arg;
        if (!ishex(c)) {
            printf("Unrecognized character '%c'\n", c);
            return 1;
        }
        arg++;

        string[i] = hexval(c) << 4;

        if (!*arg) {
            printf("Odd number of characters\n");
            return 1;
        }
        c = *arg;

        if (!ishex(c)) {
            printf("Unrecognized character '%c'\n", c);
            return 1;
        }
        arg++;

        string[i] |= hexval(c);
        i++;
    }

    // Add the terminating null byte
    string[i] = '\0';
    return 0;
}

uint8_t new_position(uint8_t *pos, uint8_t direction)
{
    uint8_t newpos;
    uint8_t upd = 1;
    int8_t x0;
    int8_t y0;
    int8_t x1;
    int8_t y1;

    x0 = *pos % XLIM;
    y0 = *pos / XLIM;

    #if DEBUG
    printf("At position (%2d, %2d)... ", x0, y0);
    #endif

    switch (direction) {
        case 0: // NW
            #if DEBUG
            printf("Moving NW... ");
            #endif
            x1 = x0 - 1;
            y1 = y0 - 1;
            break;
        case 1: // NE
            #if DEBUG
            printf("Moving NE... ");
            #endif
            x1 = x0 + 1;
            y1 = y0 - 1;
            break;
        case 2: // SW
            #if DEBUG
            printf("Moving SW... ");
            #endif
            x1 = x0 - 1;
            y1 = y0 + 1;
            break;
        case 3: // SE
            #if DEBUG
            printf("Moving SE... ");
            #endif
            x1 = x0 + 1;
            y1 = y0 + 1;
            break;
        default: // Should never happen
            #if DEBUG
            printf("INVALID DIRECTION %d!!!", direction);
            #endif
            x1 = x0;
            y1 = y0;
            break;
    }

    // Limit the range of x1 & y1
    if (x1 < 0) {
        x1 = 0;
    } else if (x1 >= XLIM) {
        x1 = XLIM - 1;
    }

    if (y1 < 0) {
        y1 = 0;
    } else if (y1 >= YLIM) {
        y1 = YLIM - 1;
    }

    newpos = y1 * XLIM + x1;
    #if DEBUG
    printf("New position (%2d, %2d)... ", x1, y1);
    #endif

    if (newpos == *pos) {
        #if DEBUG
        printf("NO CHANGE");
        #endif

        upd = 0;
    } else {
        *pos = newpos;
    }

    #if DEBUG
    printf("\n");
    #endif

    return upd;
}

void drunken_walk(void)
{
    uint8_t pos;
    uint8_t upd;
    uint16_t idx;
    uint8_t i;
    uint8_t temp;

    pos = 76;
    for (idx = 0; string[idx]; idx++) {
        temp = string[idx];

        #if DEBUG
        printf("Walking character index %d ('%02x')...\n", idx, temp);
        #endif

        for (i = 0; i < 4; i++) {
            upd = new_position(&pos, temp & 3);
            if (upd) {
                array[pos]++;
            }
            temp >>= 2;
        }
    }

    array[pos] = 16; // End
    array[76] = 15; // Start
}

int main(int argc, char *argv[])
{
    if (argc != 2) {
        printf("Usage: bishop <hex string>\n");
        return 1;
    }

    if (convert_string(argv[1])) {
        printf("String conversion failed!\n");
        return 1;
    }

    drunken_walk();
    print_graph();

    return 0;
}

Pour l'utiliser, procédez comme suit:

  1. Mettez le code source dans un fichier:
    • Ouvrez gedit ou votre éditeur de texte préféré.
    • Collez le code source ci-dessus.
    • Enregistrez-le sous bishop.c.
  2. Compilez le code en cours d'exécution gcc bishop.c -o bishop.
  3. Voir l'art aléatoire de n'importe quel fichier (où myfileest le fichier):

    ./bishop $(sha512sum myfile | cut -f1 -d ' ')
    
  4. Créez un script personnalisé pour visualiser l'art aléatoire de n'importe quel fichier:

    • Créez le dossier binaires local s'il n'existe pas:

      sudo mkdir -p /usr/local/bin
      
    • Créez un fichier sur ce dossier avec le script:

      sudo touch /usr/local/bin/randomart
      
    • Accordez des autorisations au fichier:

      sudo chmod 777 /usr/local/bin/randomart
      
    • Exécutez gedit /usr/local/bin/randomartpour modifier le fichier et collez-le dessus:

      #!/bin/bash
      
      bishop $(sha512sum "$@" | cut -f1 -d ' ')
      
    • Enregistrez le fichier.

    • Copiez le programme que nous avons construit à l'étape précédente dans le dossier binaires local:

      sudo cp bishop /usr/local/bin/
      
    • Donnez l'autorisation d'exécution au binaire:

      sudo chmod a+x /usr/local/bin/bishop
      
  5. Utilisez le programme nouvellement créé exécutant randomart myfileoù se myfiletrouve le fichier.

Hélio
la source
1
Très impressionnant
AB
2

La page OpenSSH Keys et The Drunken Bishop donne une bonne introduction au fonctionnement de l'algorthm.

Les détails de celui-ci peuvent être trouvés dans
The drunken bishop: An analysis of the OpenSSH fingerprint visualization algorithm .

Le sujet est abordé sous une forme plus générale dans l'article
"Visualisation par hachage: une nouvelle technique pour améliorer la sécurité dans le monde réel", Perrig A. et Song D., 1999, Atelier international sur les techniques cryptographiques et le commerce électronique (CrypTEC 1999). ) " .

Volker Siegel
la source
Je peux générer une somme de contrôle MD5 de tout fichier qui n'est pas une clé ssh publique comme, par exemple, un fichier JPG. Comment puis-je obtenir le randomart de ce MD5?
Tulains Córdova
+10: Vous m'avez donné le point de départ. ;-)
Helio