Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    Convertire una stringa in array di byte

    Ciao a tutti,

    ho questo problema:

    ho implementato una applicazione in java che prevede un form per l'iscrizione e un form per il login. Quando faccio il login devo confrontare le password dell'utente (quella salvata nel database con quella appena inserita). Al momento dell'inserimento nel database ho usato salt, l'ho concatenato alla password e ho fatto l'hash. All'hash ho concatenato il salt (in definitiva ho salvato il salt+hash nel database). Nel database mi sono salvato anche il salt relativo all'utente (altrimenti come faccio a ricostruire l'hash da confrontare?) e qui arriva il problema. Il salt è una stringa nel database (varchar) e mi serve come array di byte per fare il confronto con l'hash. La domanda è: come faccio a convertire il salt (che nel db è una stringa) in array di byte? Mi serve un array di byte perché ho una funzione che mi calcola il digest e vuole in input un array di byte. Probabilmente per gestire le password ci sono altri modi che non conosco. Spero che abbiate capito il problema. Questo è il codice:

    codice:
    public static byte[] digest(byte[] password, byte[] salt) {
            MessageDigest sha = null;
            try {
                sha = MessageDigest.getInstance("MD5");
            // SHA = Secure Hash Algorithm, standard del NIST
            } catch (NoSuchAlgorithmException e) {
                System.out.println("Algoritmo richiesto non supportato");
            }
            sha.update(salt);
            sha.update(password);
            byte[] impronta = sha.digest();
            byte[] risultato = new byte[impronta.length + salt.length];
            System.arraycopy(impronta, 0, risultato, 0, impronta.length);
            System.arraycopy(salt, 0, risultato, impronta.length, salt.length);
            return risultato;
        }
    
        public static byte[] getSalt(byte[] digest) {
            byte[] salt = new byte[12];
            System.arraycopy(digest, digest.length - 12, salt, 0, salt.length);
            return salt;
        }
    
        public static boolean verify(byte[] passSulDB, byte[] passInChiaro) {
            byte[] saltSulDB = getSalt(passSulDB);
            byte[] digest2 = digest(passInChiaro, saltSulDB);
            if (passSulDB.length != digest2.length) {
                return false;
            } else {
                for (int i = 0; i < passSulDB.length; ++i) {
                    if (passSulDB[i] != digest2[i]) {
                        return false;
                    }
                }
                return true;
            }
        }

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Convertire una stringa in array di byte

    Originariamente inviato da lopinsjk
    La domanda è: come faccio a convertire il salt (che nel db è una stringa) in array di byte?
    Quando si parla di conversione da String a byte (o viceversa) entra in gioco la questione del "charset". Quale???
    Comunque String ha diversi getBytes(), vedi javadoc.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    77
    getBytes() non funziona bene ora ti posto una soluzione non fatta da me che però uso

    codice:
    /**
    * A Base64 Encoder/Decoder.
    *
    * 
    
    
    * This class is used to encode and decode data in Base64 format as described in RFC 1521.
    *
    * 
    
    
    * This is "Open Source" software and released under the GNU/LGPL license.
    
    * It is provided "as is" without warranty of any kind.
    
    * Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
    
    * Home page: www.source-code.biz
    
    *
    * 
    
    
    * Version history:
    
    * 2003-07-22 Christian d'Heureuse (chdh): Module created.
    
    * 2005-08-11 chdh: Lincense changed from GPL to LGPL.
    
    * 2006-11-21 chdh:
    
    *   Method encode(String) renamed to encodeString(String).
    
    *   Method decode(String) renamed to decodeString(String).
    
    *   New method encode(byte[],int) added.
    
    *   New method decode(String) added.
    
    */
    
    public class Base64Coder {
    
    // Mapping table from 6-bit nibbles to Base64 characters.
    private static char[]    map1 = new char[64];
       static {
          int i=0;
          for (char c='A'; c<='Z'; c++) map1[i++] = c;
          for (char c='a'; c<='z'; c++) map1[i++] = c;
          for (char c='0'; c<='9'; c++) map1[i++] = c;
          map1[i++] = '+'; map1[i++] = '/'; }
    
    // Mapping table from Base64 characters to 6-bit nibbles.
    private static byte[]    map2 = new byte[128];
       static {
          for (int i=0; i<map2.length; i++) map2[i] = -1;
          for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
    
    /**
    * Encodes a string into Base64 format.
    * No blanks or line breaks are inserted.
    * @param s  a String to be encoded.
    * @return   A String with the Base64 encoded data.
    */
    public static String encodeString (String s) {
       return new String(encode(s.getBytes())); }
    
    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted.
    * @param in  an array containing the data bytes to be encoded.
    * @return    A character array with the Base64 encoded data.
    */
    public static char[] encode (byte[] in) {
       return encode(in,in.length); }
    
    /**
    * Encodes a byte array into Base64 format.
    * No blanks or line breaks are inserted.
    * @param in   an array containing the data bytes to be encoded.
    * @param iLen number of bytes to process in <code>in</code>.
    * @return     A character array with the Base64 encoded data.
    */
    public static char[] encode (byte[] in, int iLen) {
       int oDataLen = (iLen*4+2)/3;       // output length without padding
       int oLen = ((iLen+2)/3)*4;         // output length including padding
       char[] out = new char[oLen];
       int ip = 0;
       int op = 0;
       while (ip < iLen) {
          int i0 = in[ip++] & 0xff;
          int i1 = ip < iLen ? in[ip++] & 0xff : 0;
          int i2 = ip < iLen ? in[ip++] & 0xff : 0;
          int o0 = i0 >>> 2;
          int o1 = ((i0 &   3) << 4) | (i1 >>> 4);
          int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
          int o3 = i2 & 0x3F;
          out[op++] = map1[o0];
          out[op++] = map1[o1];
          out[op] = op < oDataLen ? map1[o2] : '='; op++;
          out[op] = op < oDataLen ? map1[o3] : '='; op++; }
       return out; }
    
    /**
    * Decodes a string from Base64 format.
    * @param s  a Base64 String to be decoded.
    * @return   A String containing the decoded data.
    * @throws   IllegalArgumentException if the input is not valid Base64 encoded data.
    */
    public static String decodeString (String s) {
       return new String(decode(s)); }
    
    /**
    * Decodes a byte array from Base64 format.
    * @param s  a Base64 String to be decoded.
    * @return   An array containing the decoded data bytes.
    * @throws   IllegalArgumentException if the input is not valid Base64 encoded data.
    */
    public static byte[] decode (String s) {
       return decode(s.toCharArray()); }
    
    /**
    * Decodes a byte array from Base64 format.
    * No blanks or line breaks are allowed within the Base64 encoded data.
    * @param in  a character array containing the Base64 encoded data.
    * @return    An array containing the decoded data bytes.
    * @throws    IllegalArgumentException if the input is not valid Base64 encoded data.
    */
    public static byte[] decode (char[] in) {
       int iLen = in.length;
       if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
       while (iLen > 0 && in[iLen-1] == '=') iLen--;
       int oLen = (iLen*3) / 4;
       byte[] out = new byte[oLen];
       int ip = 0;
       int op = 0;
       while (ip < iLen) {
          int i0 = in[ip++];
          int i1 = in[ip++];
          int i2 = ip < iLen ? in[ip++] : 'A';
          int i3 = ip < iLen ? in[ip++] : 'A';
          if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int b0 = map2[i0];
          int b1 = map2[i1];
          int b2 = map2[i2];
          int b3 = map2[i3];
          if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
             throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
          int o0 = ( b0       <<2) | (b1>>>4);
          int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
          int o2 = ((b2 &   3)<<6) |  b3;
          out[op++] = (byte)o0;
          if (op<oLen) out[op++] = (byte)o1;
          if (op<oLen) out[op++] = (byte)o2; }
       return out; }
    
    // Dummy constructor.
    private Base64Coder() {}
    
    } // end class Base64Coder

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    @KuWa: quando posti del codice, inseriscilo all'interno degli appositi tag CODE previsti dal forum... l'ho fatto io sul tuo post.

    ... poi mi dovrai spiegare perchè secondo te getBytes() di String non funziona bene... e soprattutto cosa c'entra un Base64 Encoder/Decoder con la richiesta dell'utente...


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    77
    Vi sono problemi di codifica e quindi è necessario usare un charset. Quindi se lui vuole convertire da stringa a array di bytes e viceversa il codice che ho postato fa tutto il necessario.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da KuWa
    Vi sono problemi di codifica e quindi è necessario usare un charset.
    Appunto ... e allora? Ne scegli uno! Ad esempio UTF-8 che è compatto e non fa "perdere" nulla. Ed è chiaro che puoi scegliere quello che vuoi ... purché sia lo stesso per codifica e decodifica!!!

    Originariamente inviato da KuWa
    Quindi se lui vuole convertire da stringa a array di bytes e viceversa il codice che ho postato fa tutto il necessario.
    Ma pure quel codice usa getBytes() e la creazione di un String da byte[] e oltretutto senza specificare un charset ... ovvero usa quello della piattaforma e quindi ... dipende.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Questa mattina forse non ho spiegato l'assurdità della cosa. Il programma che ho implementato, per la maggior parte delle volte, funziona e mi restituisce output di questo tipo:

    codice:
    Salt creato dall'utente
     124 11 -85 27 78 115 -126 -55
    Password creata dall'utente
     -24 126 -8 -120 45 110 127 -43 96 27 -4 35 63 -128 -4 -114 124 11 -85 27 78 115 -126 -55
    salt tirato fuori dal database
     124 11 -85 27 78 115 -126 -55
    password tirata fuori dal database
     -24 126 -8 -120 45 110 127 -43 96 27 -4 35 63 -128 -4 -114 124 11 -85 27 78 115 -126 -55
    Ciascun set di numeri è un array di byte. Come potete vedere il salt creato dall'utente è quello iniziale e la password è quella inserita al momento dell'iscrizione. Il salt che estraggo dal database invece è quello che ottengo dopo la query (e come vedete in questo caso coincide con il salt iniziale) e la password lo stesso.

    Per fare le conversioni di cui vi parlavo stamattina uso questa classe:

    codice:
    public class Funzioncine {
    
        public static String ArrayToString(byte[] b) {
            return new String(b);
        }
    
        public static byte[] StringToArray(String s) {
            return s.getBytes();
        }
    
        public static byte[] charArrayToByteArray(char[] c) {
            int length = c.length;
            byte[] byteArray = new byte[length * 2];
            for (int i = 0; i < length; i = i + 2) {
                byteArray[i] = (byte) (c[i] & 0xff);
                byteArray[i + 1] = (byte) (c[i] >> 8 & 0xff);
            }
            return byteArray;
        }
    }
    Dove sta il problema? Lo vediamo insieme (ed è assurdo secondo me) in questo output (in cui le password non coincidono):

    codice:
    Salt creato dall'utente
     103 -32 126 94 118 -88 77 64
    Password creata dall'utente
     52 -30 -31 -36 -127 -117 113 -43 102 -68 -128 -13 41 9 60 -29 103 -32 126 94 118 -88 77 64
    salt tirato fuori dal database
     103 -32 126 94 118 -88 77 64
    password tirata fuori dal database
     52 -30 -31 -36 63 -117 113 -43 102 -68 -128 -13 41 9 60 -29 103 -32 126 94 118 -88 77 64
    Se osservate bene i salt coincidono ma la cosa fantastica è quel -127 (quinto elemento della password creata dall'utente) che diventa 63 nella password estratta dal database! Questo è l'errore che non capisco e naturalmente le password non oincidono e non riesco a fare il login. Ma la cosa ancora più fantastica è che ogni volta che ottengo un errore di questo tipo, i numeri che non coincidono vengono codificati sempre con il 63!!! Questo può avvenire anche nel salt ma non è questo il caso.

    Io sono completamente incredulo..

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2002
    Messaggi
    77
    io avevo questo tuo problema. E' vero che puoi usare qualsiasi charset. Ma uno vale l'altro e quella classe funziona.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.