IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Sécurité Discussion :

vigenere avec deux clefs de 512bits, facilement cassable ?


Sujet :

Sécurité

  1. #1
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut vigenere avec deux clefs de 512bits, facilement cassable ?
    Bonjour,

    Il y a quelque jours, après avoir oublié un mot de passe, j'ai décider de me programmer (j'aime bien me faire mes propres outils) un programme de chiffrement.

    Etant néophyte complet en cryptographie, j'ai finalement opté pour une ascii_table de vigenere, facile à implémenter.

    Avant de vous exposer l'algorithme (je pars du principe que vous connaissez le principe de la table de vigenere), voici ma question : j'ai lu que ce chiffrement à été cassé par un mathématicien, de prima bord à quelle échelle de temps peut-on estimer casser mon algorithme ?

    Maintenant l'algo en question :
    • il y a deux mots de passe, pass1 et pass2
    • un hash SHA-512 est créer pour chacun d'eux, H1 et H2
    • deux tables ascii vigenere sont utilisée, la première (table1 est constante et classique, la seconde est crée de la façon suivante :
      1. ref_char est égal à la somme des valeurs de pass2 modulo 256
      2. ref_char est utilisé en combinaison avec table1 sur tous les caractères de cette dernière de façon à obtenir 256 caractères, c'est la table_2
    • le texte clair est codé une première fois à l'aide de table1 et de H1, le résultat est appelé first_pass
    • first_pass est encodé à son tour à l'aide de table2 et de H2, le résultat est appelé second_pass
    • enfin, second_pass est retourné comme résultat


    Si le cassage se mesure en minutes, alors, j'opterai sûrement pour une méthode plus sûre, si en revanche les moyens à déployer sont importants pour un temps raisonable, alors je peux tranquilement conserver cette méthode, l'intérêt/gain n'étant pas suffisament grand pour justifier un tel déploiement de moyens. D'où ma question

    Merci

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

    Je ne connais pas Vigenère mais je lis sur wikipédia que le chiffre de Vigenère a été cassé depuis longtemps (1863).

    Donc je ne sais pas si c'est cela que tu cherchais.

  3. #3
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Oui, j'ai bien vu que ce code à été cassé, mais je pense encore naïvement que la deuxième table crée à partir du second mot de passe en conjonction avec une deuxième passe augmente fortement la difficulté de cassage. Et je dit naïvement car je n'ai pas de connaissances particulières en mathématiques...

    voici le code source en python :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    import itertools as it
    import hashlib as hl
     
    table = ''.join(chr(x) for x in range(256))
     
    def vi_code(table, clear, code):
        '''=> <str> one coded character
        args :
            table <- <str> 256 characters
            clear <- <str> one character
            code  <- <str> one character'''
        return table[ ( ord(clear) + ord(code) ) % 256 ]
     
    def vi_decode(table, crypted, code):
        '''=> <str> one decoded character
        args :
            table   <- <str> 256 characters
            crypted <- <str> one character
            code    <- <str> one character'''
        for c in table:
            if vi_code(table, c, code) == crypted:
                return c
     
    def encode_text(text, pass1, pass2):
        '''=> <str> encoded text
        args :
            text  <- <str> clear text
            pass1 <- <str> password 1
            pass2 <- <str> password 2'''
        table2 = chr(sum([ord(c) for c in pass2]) % 256)
        table2 = ''.join(vi_code(table, c, table2) for c in table)
        hash1 = hl.sha512(pass1).digest()
        hash2 = hl.sha512(pass2).digest()
        h1_cycle = it.cycle(hash1)
        h2_cycle = it.cycle(hash2)
        first_pass = ''.join(vi_code(table, c, h1_cycle.next()) for c in text)
        second_pass = ''.join(vi_code(table2, c, h2_cycle.next()) for c in first_pass)
        return second_pass
     
    def decode_text(text, pass1, pass2):
        '''=> <str> decoded text
        args :
            text  <- <str> coded text
            pass1 <- <str> password 1
            pass2 <- <str> password 2'''
        table2 = chr(sum([ord(c) for c in pass2]) % 256)
        table2 = ''.join(vi_code(table, c, table2) for c in table)
        hash1 = hl.sha512(pass1).digest()
        hash2 = hl.sha512(pass2).digest()
        h1_cycle = it.cycle(hash1)
        h2_cycle = it.cycle(hash2)
        second_pass = ''.join(vi_decode(table2, c, h2_cycle.next()) for c in text)
        first_pass = ''.join(vi_decode(table, c, h1_cycle.next()) for c in second_pass)
        return first_pass

    et voici un exemple de texte codé:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    # as a string
    '\xa3\x0e\xb7"\x13\'M\xcc-\x04\xa5\x80\xb4\xb0\xba\xd2\x02\x00@\xe2\x07<l=\xbd\xe3\xa1\x02\xc7h-=\xe4%\xdd\xb4\xd3\x07\x86\x01#\xcf\xa4F\xaa'
     
    #as hex values of each byte (spaces are just candies to beautify the stuff)
    'a3 0e b7 22 13 27 4d cc 2d 04 a5 80 b4 b0 ba d2 02 00 40 e2 07 3c 6c 3d bd e3 a1 02 c7 68 2d 3d e4 25 dd b4 d3 07 86 01 23 cf a4 46 aa'

    si par hasard quelqu'un veut s'amuser à le casser...

    edit : l'avantage du hashage des mots de pass est que la longueur du mot de passe n'a pas besoin d'être particulièrement grand (un minimum quand même). En revanche le gros désavantage est que la taille des clés de codages sont connues (64 octets)

  4. #4
    Membre du Club

    Homme Profil pro
    Expert sécurité informatique
    Inscrit en
    Août 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 33
    Points : 64
    Points
    64
    Par défaut Pas solide
    Si je comprend bien ce qu'il se passe tu utilises deux substitutions "vigenere-like" consécutives avec une clef de 64 octets à chaque fois.

    Les deux clefs faisant la même taille j'ai l'intuition que ça revient à utiliser une seule substitution en "vigenere-like" avec une clef de 64 octets (et, par conséquent, que ça n'est pas solide).

    Par contre, aussi faible que soit l'algorithme de chiffrement utilisé, il faudra un peu plus que 45 octets chiffrés pour le casser rapidement puisqu'il se base tout de même sur des clefs de 64 octets

  5. #5
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Merci , j'ai modifié le code source pour générer des clés au moins aussi longues que le texte à chiffrer (une mise bout a bout de hashs de différentes parties d'une pass phrase (dont le minimum de caractères diffère selon la longueur du texte à encodé)

    Si j'ai donc bien compris tes propos et le lien communiqué par Neckara, tant que les clés sont plus longues que le texte (qui ne sera jamais très grand, simple keyring), ça ne se casse pas facilement/rapidement ... c'est bien ça ?

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    import itertools as it
    import hashlib as hl
     
    table = ''.join(chr(x) for x in range(256))
     
    def vi_code(table, clear, code):
        '''=> <str> one coded character
        args :
            table <- <str> 256 characters
            clear <- <str> one character
            code  <- <str> one character'''
        return table[ ( table.index(clear) + table.index(code) ) % 256 ]
     
    def vi_decode(table, crypted, code):
        '''=> <str> one decoded character
        args :
            table   <- <str> 256 characters
            crypted <- <str> one character
            code    <- <str> one character'''
        return table[ ( table.index(crypted) - table.index(code) ) % 256 ]
     
    def _pwd_min_len(text_len):
        '''=> <int>
        args :
            text_len <- <int> length of the text to cipher'''
        d, m = divmod(text_len, 64)
        return d+bool(m)
     
    def _pwd_advised_len(text_len):
        return _pwd_min_len(text_len) * 32
     
    def _pwd_normalize(required_len, pwd):
        return pwd * ( (required_len // len(pwd)) + 1 )
     
    def _create_key(text_len, pwd):
        if _pwd_advised_len(text_len) > len(pwd) :
            pwd = _pwd_normalize(_pwd_advised_len(text_len),pwd)
        hash_times = _pwd_min_len(text_len)
        return ''.join(hl.sha512(pwd[i::hash_times]).digest() for i in range(hash_times))
     
    def encode_text(text, pass1, pass2):
        '''=> <str> encoded text
        args :
            text  <- <str> clear text
            pass1 <- <str> password 1
            pass2 <- <str> password 2'''
        table2 = chr(sum(ord(c) for c in pass2) % 256)
        table2 = ''.join(vi_code(table, c, table2) for c in table)
        text_len = len(text)
        hash1 = _create_key(text_len, pass1)
        hash2 =  _create_key(text_len, pass2)
        h1_cycle = it.cycle(hash1)
        h2_cycle = it.cycle(hash2)
        first_pass = ''.join(vi_code(table, c, h1_cycle.next()) for c in text)
        second_pass = ''.join(vi_code(table2, c, h2_cycle.next()) for c in first_pass)
        return second_pass
     
    def decode_text(text, pass1, pass2):
        '''=> <str> decoded text
        args :
            text  <- <str> coded text
            pass1 <- <str> password 1
            pass2 <- <str> password 2'''
        table2 = chr(sum(ord(c) for c in pass2) % 256)
        table2 = ''.join(vi_code(table, c, table2) for c in table)
        text_len = len(text)
        hash1 = _create_key(text_len, pass1)
        hash2 =  _create_key(text_len, pass2)
        h1_cycle = it.cycle(hash1)
        h2_cycle = it.cycle(hash2)
        second_pass = ''.join(vi_decode(table2, c, h2_cycle.next()) for c in text)
        first_pass = ''.join(vi_decode(table, c, h1_cycle.next()) for c in second_pass)
        return first_pass

  6. #6
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Mais si tu veux chiffrer/déchiffrer des données, pourquoi ne pas utiliser des méthodes "contemporaines" qui sont encore "sûre" comme le Blowfish (je dois écorcher le nom ) ou le RSA ?

  7. #7
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Héhéhé, parceque ça m'amuse de réinventer la roue et que mon ego aime bien, houhouhou.

    Qui plus est, vigénere, ça reste à ma petite portée. Si je suis bien le truc, la grosse faiblesse du truc vient des redondances du pattern de la clé et de certains mots du texte, tel ("le","the"). Mes mots de passes (ceux à chiffrer) étant assez différents, peu de redondances dans le texte clair, et pour les clés de codage... bah c'est basé sur des hashs, et elles sont maintenant toutes au moins aussi longues que le texte clair, deuxième faiblesse couverte. La troisième faiblesse que je verrais de façon entièrement intuitive, c'est l'ordre des 256 caractères de la table ascii...

    Or j'ai encore pensé à une méthode supplémentaire : utiliser une méthode pseudo aléatoire de shuffle sur la table de départ qui peut constament reproduire les même résultats, pourvu que la même valeur lui soit passé en second argument... ce qui fait 256^256 solutions quand même...

    Et puis, si vraiment ce n'est pas suffisant, je m'attaquerai comme tu le dis, à des algo aujourd'hui considérés comme "sûrs". Mais j'aime l'idée qu'une méthode "simple" peut être très efficace.

  8. #8
    Membre du Club

    Homme Profil pro
    Expert sécurité informatique
    Inscrit en
    Août 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Expert sécurité informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 33
    Points : 64
    Points
    64
    Par défaut La force d'une chaine c'est celle de son maillon le plus faible
    Réinventer la roue c'est amusant (c'est l'un de mes passe temps favoris ), mais en crypto il ne faut pas s'attendre à ce que ça donne de bons résultats.

    Je te conseille donc de te tourner vers des algorithmes "sûrs" ou, encore mieux, vers des outils "sûrs" si jamais tu as l'intention de stocker tes vrais mots de passe (en effet, les erreurs à l'implémentations peuvent être dramatiques en termes d'impacts sur la sécurité apportée; et je ne te parle même pas des empreintes mémoires que tu vas laisser un peu partout avec un programme en python ^^ ...). En revanche, si c'est juste pour jouer, tu peux te faire plaisir à pondre tes propres softs

  9. #9
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Arf, zut, flûte, crotte !

    Bon, je vais utiliser keypass, ou openpgp...

    En attendant, j'me serais bien ammusé... pour le fun je vais m'interesser à à d'autres algorithmes, nottament celui cité par Neckara

    Faudra que je m'interesse de plus près également au fonctionnement du ramasse miette de python, à moins que tu ne me dises de suite qu'il laisse plein d'empreinte mémoire lui aussi (ce serait couillon, y'a que python que je connais )

    Ah mais j'y pense, heu... et Pypy, beaucoup d'empreintes mémoires ?

Discussions similaires

  1. Connect BY avec deux clefs et deux "Start with"
    Par clousot dans le forum Requêtes
    Réponses: 1
    Dernier message: 17/12/2008, 11h19
  2. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25
  3. [CR] instruction If avec deux opérations
    Par MaDmAtT dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 19/07/2004, 13h54
  4. Réponses: 10
    Dernier message: 10/06/2004, 16h20
  5. [langage] split avec deux motifs (Newbie)
    Par Raumsog II dans le forum Langage
    Réponses: 2
    Dernier message: 07/06/2004, 09h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo