Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 20/02/2025, à 20:23

diesel

[RÉSOLU] Clé publique openssh

Bonsoir,

Je recherche comment extraire le produit rsa d'une clé publique openssh.

Pour l'instant, tout ce que je trouve, c'est : une clé openssh commence par ssh-rsa, puis une chaîne commençant par AAAA et se terminant par =, puis le nom d'utilisateur@nom de machine, ce qui ne m'avance pas beaucoup (je savais déjà).

En fait, ce que je cherche, c'est le format de la chaîne commençant par AAAA mais je ne trouve rien.

Quelqu'un connaît ?

Amicalement.

Jean-Marie

Dernière modification par diesel (Le 20/02/2025, à 21:57)


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

En ligne

#2 Le 20/02/2025, à 21:43

Vobul

Re : [RÉSOLU] Clé publique openssh

HUMAIN - VOBUL

Le format est décrit ici : https://datatracker.ietf.org/doc/html/r … ection-6.6

chatgpt o3-mini-high:

La clé publique RSA au format OpenSSH est en réalité une chaîne Base64 qui encode une structure binaire définie par le protocole SSH. Pour une clé RSA, cette structure se compose de trois éléments principaux:

    L’algorithme
    – Un entier 32 bits (big-endian) qui indique la longueur de la chaîne suivante, qui doit être "ssh‑rsa".
    – La chaîne de caractères "ssh-rsa" elle-même.

    L’exposant (e)
    – Un entier 32 bits indiquant la longueur du champ de l’exposant.
    – Le champ correspondant, qui est un mpint (entier à précision multiple) représentant l’exposant public.

    Le module (n)
    – Un entier 32 bits indiquant la longueur du champ du module.
    – Le champ correspondant, qui est également un mpint et représente le produit RSA, c’est-à-dire le résultat de p×qp×q.

Ainsi, la chaîne qui commence par "AAAA" est le résultat de l’encodage Base64 de cette séquence binaire. Pour extraire le "produit RSA" (le module nn), il suffit de décoder la chaîne Base64 et de parser la structure en suivant l’ordre décrit ci-dessus.

Pour résumer, le format binaire encodé en Base64 est:

string    "ssh-rsa"
mpint     e
mpint     n   <-- ici se trouve le produit RSA (module)

Vous pouvez par exemple utiliser un script en Python pour décoder et extraire ces valeurs. La RFC4253 (section 6.6) fournit plus de détails sur ce format.


chatgpt 4o
Bonsoir Jean-Marie,

La chaîne commençant par `AAAA` est une clé publique OpenSSH encodée en Base64. Son format suit la spécification **SSH Public Key File Format**, qui est une structure binaire sérialisée et encodée en Base64.

Format de la clé publique OpenSSH (RSA) 
Une clé publique RSA dans OpenSSH est généralement sous la forme :

ssh-rsa AAAAB3... contenu_base64 ...= utilisateur@machine

L'encodage Base64 contient les données suivantes sous forme binaire :

  1. **"ssh-rsa"** (chaîne de type `string`)

  2. **Exposant (`e`)** (entier en `mpint`)

  3. **Modulus (`n`)** (entier en `mpint`)

Extraction du Modulus (n) et de l’Exposant (e) 
Si tu veux extraire ces valeurs depuis une clé publique OpenSSH, tu peux utiliser `ssh-keygen` ou `openssl` :

1. Avec `ssh-keygen` 
Tu peux convertir la clé publique OpenSSH en format OpenSSL avec :

ssh-keygen -e -m PKCS8 -f clé.pub

Mais cela ne te donne pas directement le modulus.

2. Avec `openssl` et `base64` 
Pour extraire la partie Base64 et la décoder :

awk '{print $2}' clé.pub | base64 -d | xxd -p

Ensuite, tu dois lire la structure binaire pour extraire `e` et `n`.

3. Avec `openssl rsa` 
Une manière plus simple est de convertir la clé en format OpenSSL et d'utiliser OpenSSL pour afficher le modulus :

ssh-keygen -e -m PKCS8 -f clé.pub > clé.pem
openssl rsa -pubin -in clé.pem -text -noout

Cela affichera :

Public-Key: (2048 bit)
Modulus:
    00:...
Exponent: 65537 (0x10001)

Le produit `n` (modulus) est la valeur que tu cherches.

---

Si tu veux un script Python pour extraire `n` et `e`, je peux t'en fournir un !

Amicalement,


Vobul
Utilisez le retour utilisable de commandes !!!
J'aime la langue française, mais je parle franglais, deal with it.
RTFM

Hors ligne

#3 Le 20/02/2025, à 21:56

diesel

Re : [RÉSOLU] Clé publique openssh

Merci mille fois Vobul. C'est exactement ce que je cherchais.

Merci encore pour ta proposition de script python, mais je vais écrire en c.

Amicalement.

Jean-Marie


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

En ligne

#4 Hier à 09:50

Vobul

Re : [RÉSOLU] Clé publique openssh

diesel a écrit :

je vais écrire en c.

Facile :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/evp.h>

/* Function to read a 4-byte big-endian unsigned integer */
uint32_t read_uint32(const unsigned char *buf) {
    return ((uint32_t)buf[0] << 24) |
           ((uint32_t)buf[1] << 16) |
           ((uint32_t)buf[2] << 8)  |
           ((uint32_t)buf[3]);
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s public_key_file\n", argv[0]);
        return 1;
    }

    /* Open the file containing the public key */
    FILE *fp = fopen(argv[1], "r");
    if (!fp) {
        perror("fopen");
        return 1;
    }

    /* Read the first line (expected format: "ssh-rsa AAAA...== user@host") */
    char line[4096];
    if (!fgets(line, sizeof(line), fp)) {
        fprintf(stderr, "Error reading file\n");
        fclose(fp);
        return 1;
    }
    fclose(fp);

    /* Tokenize the line */
    char *token = strtok(line, " ");
    if (!token || strcmp(token, "ssh-rsa") != 0) {
        fprintf(stderr, "Not an ssh-rsa key\n");
        return 1;
    }

    /* Get the Base64-encoded part */
    token = strtok(NULL, " ");
    if (!token) {
        fprintf(stderr, "No Base64 key data found\n");
        return 1;
    }
    char *b64 = token;
    b64[strcspn(b64, "\n")] = 0;  // Remove newline if present

    /* Decode the Base64 string */
    int b64_len = strlen(b64);
    int decoded_len = 3 * b64_len / 4;  // Allocate enough space
    unsigned char *decoded = malloc(decoded_len);
    if (!decoded) {
        perror("malloc");
        return 1;
    }

    int out_len = EVP_DecodeBlock(decoded, (unsigned char *)b64, b64_len);
    if (out_len < 0) {
        fprintf(stderr, "Base64 decoding error\n");
        free(decoded);
        return 1;
    }

    /* Parse the binary structure:
       [string "ssh-rsa"][mpint e][mpint n]
    */
    unsigned char *p = decoded;
    int remain = out_len;

    /* Read the key type (string "ssh-rsa") */
    if (remain < 4) {
        fprintf(stderr, "Invalid data (key type length missing)\n");
        free(decoded);
        return 1;
    }
    uint32_t key_type_len = read_uint32(p);
    p += 4;
    remain -= 4;
    if (remain < key_type_len) {
        fprintf(stderr, "Invalid data (key type string incomplete)\n");
        free(decoded);
        return 1;
    }
    /* Skip the key type string */
    p += key_type_len;
    remain -= key_type_len;

    /* Read the exponent (mpint e) */
    if (remain < 4) {
        fprintf(stderr, "Invalid data (exponent length missing)\n");
        free(decoded);
        return 1;
    }
    uint32_t e_len = read_uint32(p);
    p += 4;
    remain -= 4;
    if (remain < e_len) {
        fprintf(stderr, "Invalid data (exponent data incomplete)\n");
        free(decoded);
        return 1;
    }
    /* Skip exponent bytes */
    p += e_len;
    remain -= e_len;

    /* Read the modulus (mpint n) */
    if (remain < 4) {
        fprintf(stderr, "Invalid data (modulus length missing)\n");
        free(decoded);
        return 1;
    }
    uint32_t n_len = read_uint32(p);
    p += 4;
    remain -= 4;
    if (remain < n_len) {
        fprintf(stderr, "Invalid data (modulus data incomplete)\n");
        free(decoded);
        return 1;
    }

    /* Print the modulus in hexadecimal format */
    printf("Modulus (n) in hex:\n");
    for (uint32_t i = 0; i < n_len; i++) {
        printf("%02x", p[i]);
    }
    printf("\n");

    free(decoded);
    return 0;
}

Puis tu le compiles avec :

gcc -o extract_modulus extract_modulus.c -lcrypto

Et pour l'utiliser :

./extract_modulus id_rsa.pub

Pour info, j'ai testé, ça fonctionne.


Vobul
Utilisez le retour utilisable de commandes !!!
J'aime la langue française, mais je parle franglais, deal with it.
RTFM

Hors ligne

#5 Hier à 10:33

diesel

Re : [RÉSOLU] Clé publique openssh

Qu'est-ce que je ferais sans toi ? lol lol lol

Merci encore. Je vais au moins gagner du temps.

Amicalement.

Jean-Marie


Je déteste qu'on cherche à me faire passer pour un con, j'y arrive déjà très bien tout seul.
Le mort, il sait pas qu'il est mort ; c'est pour les autres que c'est dur.................... Pour les cons, c'est pareil.

En ligne