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

Langage Java Discussion :

Cryptage 3DES : problème


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut Cryptage 3DES : problème
    Bonjour,

    On me donne un exemple de mot de passe, clé :
    Mot de passe : 123456789?;ABC
    -->le convertir en ASCII et faire un padding pour que ça tienne sur 16
    (ça doit donc donner 3132333435363738393F3B4142430000)
    Cryptage : 3DES mode ECB
    Clé :
    152618515457CD7A
    8C38160BB96B5D52
    -->apparemment la clé est partie1partie2partie1, soit 152618515457CD7A8C38160BB96B5D52152618515457CD7A
    KCV : E3C0A6 (ça je sais pas quoi en faire)

    Bref, ce que je dois obtenir au final c'est 1AAB8A8DEF38FBECF28219739DCEA300

    ce que j'obtient :
    password : 123456789?;ABC
    password ASCII à crypter : 3132333435363738393f3b4142430000
    password crypté: qêíšÕz ý2LMŒQ š‘ÖªOcMÐ ®Nìw²;
    password ASCII décrypté: 3132333435363738393f3b4142430000
    Code ci-dessous.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Code : 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
    74
    75
    76
    77
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESedeKeySpec;
    import javax.crypto.spec.SecretKeySpec;
     
    import org.apache.commons.lang.StringUtils;
     
    public class SymetricEncryptor {
    	private static String hexachars = "0123456789abcdef";
    	private static String TRANSFORMATION = "DESede/ECB/Nopadding";
    	private static String ALGORITHM = "DESede";
    	private static int SIZE_PWD = 16;
     
    	public static void main(String[] args) throws Exception {
     
        String sInput = "123456789?;ABC";  
        String sInputAscii = toHex(sInput.getBytes());
        sInputAscii = StringUtils.rightPad(sInputAscii, 2*SIZE_PWD, '0');
     
    	byte[] input = sInputAscii.getBytes();//"3132333435363738393F3B4142430000".getBytes();
        byte[] theKey = "152618515457CD7A8C38160BB96B5D52152618515457CD7A".getBytes();
     
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        SecretKey secretKey = null;
     
        SecretKeyFactory skf = SecretKeyFactory.getInstance(ALGORITHM);
        DESedeKeySpec ks = new DESedeKeySpec(theKey);
        secretKey = skf.generateSecret(ks);
     
        System.out.println("password : " + sInput);
        System.out.println("password ASCII à crypter : " + sInputAscii);
     
        // encryption pass
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
        int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
        ctLength += cipher.doFinal(cipherText, ctLength);
     
     
        System.out.println("password crypté: " + new String(cipherText) );
     
        //String mdp = "1AAB8A8DEF38FBECF28219739DCEA300";
        //cipherText = mdp.getBytes();
     
        // decryption pass
        SecretKey decryptionKey = new SecretKeySpec(secretKey.getEncoded(), secretKey.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, decryptionKey);
        byte[] plainText = new byte[cipher.getOutputSize(ctLength)];       
        int ptLength = cipher.update(cipherText, 0, ctLength, plainText, 0);
        ptLength += cipher.doFinal(plainText, ptLength);
     
        System.out.println("password ASCII décrypté: " + new String(plainText));
      }
     
        public static String toHex(byte[] data, int length)
        {
            StringBuffer  buf = new StringBuffer();
     
            for (int i = 0; i != length; i++)
            {
                int v = data[i] & 0xff;
     
                buf.append(hexachars.charAt(v >> 4));
                buf.append(hexachars.charAt(v & 0xf));
            }
     
            return buf.toString();
        }
     
        public static String toHex(byte[] data)
        {
            return toHex(data, data.length);
        }
     
     
    }

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 766
    Par défaut
    Bonjour,

    Pour moi vous vous êtes embrouillé avec les représentations hexa en String et les octets obtenu avec la méthode getbytes.

    Par exemple si je fais : "FFFFFFFF".getbytes()
    Je vais obtenir en base 10 : 70 70 70 70 70 70 70 70 70
    Soit la valeur du caractère 'F' et non 255.

    Revoyez votre code pour tenir compte de ça.


    Ensuite je pense qu'il y a un soucis de compréhension dans le fonctionnement de l'algorithme DES. Chaque clé fait en fait 56 bits et 8 bits pour le check de parité. Le KCV (pour Key Check Value) sert dans ce check lorsque les 3 morceaux de la clé sont assemblées.

    Ainsi en chiffrant trois bytes à 0 avec ta clé on obtient : E3C0A6 ce qui permet de valider ta clé quand elle est transmise.

    Tout ça pour dire qu'au final, tu colles dans ton constructeur DESedeKeySpec, 48 bytes alors qu'un keyspec tripleDES c'est 24 bytes. Donc déjà au départ ta clé n'est pas la bonne.





    Bon courage,

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Merci pour ta réponse.

    En fait a priori c'est pas la clé qui pose problème c'est la transformation de String en tableau de bytes (bizarrement getByte ne fait pas ce que je veux!)

    Avec ça, ça marche beaucoup mieux (tout en gardant ma clé sur 48 bits):
    Code : 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
    	public static byte[] toBytes(String s){
     
    		int len = s.length();
     
    		assert len % 1 == 0 : "longueur impair";
     
    		byte[] data = new byte[len / 2];
     
    		for (int i = 0; i < len; i += 2) {
    			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
     
    		}
     
    		return data;
     
    	}

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par stof Voir le message
    En fait a priori c'est pas la clé qui pose problème c'est la transformation de String en tableau de bytes (bizarrement getByte ne fait pas ce que je veux!)

    Avec ça, ça marche beaucoup mieux (tout en gardant ma clé sur 48 bits):
    Code : 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
    	public static byte[] toBytes(String s){
     
    		int len = s.length();
     
    		assert len % 1 == 0 : "longueur impair";
     
    		byte[] data = new byte[len / 2];
     
    		for (int i = 0; i < len; i += 2) {
    			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
     
    		}
     
    		return data;
     
    	}
    Mais... C'est pas malin, à quoi ça t'a servi de passer par une notation hexa, si tu veux ensuite décoder cet hexa ? Il fallait appeler getBytes() sur la String d'origine directement.
    (En fait, getBytes("us-ascii") de préférence. Ça évite les incohérences d'un ordi à l'autre en cas de caractères non-ascii.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 766
    Par défaut
    Citation Envoyé par stof Voir le message
    Avec ça, ça marche beaucoup mieux (tout en gardant ma clé sur 48 bits):
    Heu... je suis pas sûr de comprendre une clé 3DES c'est sur 192 bits, il y a un soucis.
    Et oui quel intérêt de décoder en String une clé ?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    759
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 759
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Mais... C'est pas malin, à quoi ça t'a servi de passer par une notation hexa, si tu veux ensuite décoder cet hexa ? Il fallait appeler getBytes() sur la String d'origine directement.
    (En fait, getBytes("us-ascii") de préférence. Ça évite les incohérences d'un ordi à l'autre en cas de caractères non-ascii.)
    C'est probablement vrai sauf pour la complétion par des "00" mais j'aurais certainement pu les ajouter dans mon tableau de bytes après, mais j'ai juste suivi les consignes.

    Citation Envoyé par Jimmy_ Voir le message
    Heu... je suis pas sûr de comprendre une clé 3DES c'est sur 192 bits, il y a un soucis.
    Et moi donc...mais ça donne bien le résultat attendu pourtant!

    Citation Envoyé par Jimmy_ Voir le message
    Et oui quel intérêt de décoder en String une clé ?
    Là j'ai pas compris la question

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Cryptage RSA - Problème
    Par alleztulle dans le forum Débuter avec Java
    Réponses: 7
    Dernier message: 23/04/2013, 18h53
  2. Cryptage 3DES & stockage SQLite
    Par steph68b dans le forum Android
    Réponses: 7
    Dernier message: 30/10/2012, 13h42
  3. [Débutant] cryptage 3DES c# / PHP
    Par vince29 dans le forum C#
    Réponses: 5
    Dernier message: 23/06/2011, 11h32
  4. Problème dans un cryptage de cesar
    Par hutchuck dans le forum Sécurité
    Réponses: 6
    Dernier message: 09/10/2005, 20h35

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