Visualizzazione dei risultati da 1 a 7 su 7

Discussione: [Jav] String e SHA1

  1. #1

    [Jav] String e SHA1

    salve!
    devo inviare dati a un db MySQL sotto forma di stringhe criptate con SHA1.
    ho provato così:
    codice:
        public boolean login(String name, String pwd) throws ClassNotFoundException, SQLException, NoSuchAlgorithmException {
            conn = DBManager.getInstance().takeConnection();
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] encodeName = name.getBytes();
            byte[] encodePwd = pwd.getBytes();
            PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE user_name = ? AND user_pass = ?");
    //        pstmt.setString(1, name);
    //        pstmt.setString(2, pwd);
            pstmt.setString(1, md.digest(encodeName).toString());
            pstmt.setString(2, md.digest(encodePwd).toString());
            ResultSet rs = pstmt.executeQuery();
            if (rs.next()) {
                User user = new User();
                user.setId(rs.getInt(0));
                user.setName(name);
                user.setPwd(pwd);
                rs.close();
                pstmt.close();
                return true;
            } else {
                rs.close();
                pstmt.close();
                return false;
            }
        }
    se nn uso SHA1 ne qui nel su db tutto funziona bene e riesco a fare il login.
    sennò nn riesco e l'autenticazione fallisce.
    avete qualche idea?

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

    Re: [Jav] String e SHA1

    Originariamente inviato da fermat
    codice:
            pstmt.setString(1, md.digest(encodeName).toString());
    Ci sono diverse questioni:

    1) Stai invocando toString() su un array. Gli array ereditano il toString() di Object che fornisce per un byte[] una stringa del tipo es. "[B@3e25a5" che a te non serve assolutamente.

    Prendi ciascun byte dell'array fornito da digest() e "formattalo" in hex a 2 caratteri e componi una stringa.
    Ammesso che la codifica esadecimale sia quello che vuoi (che è un caso tipico). Se fosse base64 o altro, devi precisarlo.

    2) Parti con la password logicamente in String. Al MessageDigest bisogna passare dei byte, quindi giustamente ottieni la sequenza di byte dal String. Il punto è che hai usato getBytes() (quello senza parametri). Questo usa il charset di "default" della piattaforma. Quale è? Dipende dalla piattaforma. Se cambi piattaforma o se il charset non fosse proprio appropriato per codificare tutti i caratteri che vuoi permettere, allora non andrebbe affatto bene.
    Per queste cose devi stabilire un charset ben preciso (es. UTF-8) affinché la conversione sia consistente e nota. Quindi devi usare il getBytes(String charsetName)

    3) Piccola considerazione. In genere è tipico e sensato mettere nel DB un "hash" della password .... non anche del nome che in genere resta in "chiaro". (ma se proprio vuoi anche del nome, ok).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    1) ok ora mi guardo come fare
    2) la codifica è UTF-8....hai ragione la imposto
    3) si infatti in genere è così, ma chi ha messo su questo db ha preferito fare così quindi mi adeguo.

    intanto grazie per la risposta!!

  4. #4
    allora, il db è tutto in utf8_general_ci.
    io ho provato così:
    codice:
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] encodeName = md.digest(name.getBytes("UTF-8"));
            byte[] encodePwd = md.digest(pwd.getBytes("UTF-8"));
            StringBuilder sbName = new StringBuilder();
            StringBuilder sbPwd = new StringBuilder();
            for (int i = 0; i < encodeName.length; i++) {
                int v = encodeName[i] & 0xff;
                sbName.append(Integer.toHexString(v));
            }
            for (int i = 0; i < encodePwd.length; i++) {
                int v = encodePwd[i] & 0xff;
                sbName.append(Integer.toHexString(v));
            }
            String convName = sbName.toString();
            String convPwd = sbPwd.toString();
    che convName e convPwd hanno dei caratteri in più rispetto a quello che c'è sul db.

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fermat
    allora, il db è tutto in utf8_general_ci.
    Non centra la codifica del DB/tabella!. Quella serve solo al DB per memorizzare la stringa nei suoi file di dati. Se per la password (e nel tuo caso anche il nome) rappresenti l'hash in esadecimale, avrai es. "1B5A8345......." che essendo roba ASCII il DB non ha problemi a memorizzarla in UTF-8, ISO-8859-1, ecc...

    Quando parlavo prima del charset intendevo quello che si deve passare a getBytes per ottenere da un String la sequenza di byte. Questo è il charset che deve essere "stabile" e appropriato. UTF-8 comunque è ottimo perché compatto e non "perde" nulla del Unicode.

    Originariamente inviato da fermat
    codice:
                int v = encodeName[i] & 0xff;
                sbName.append(Integer.toHexString(v));
    toHexString fornisce la rappresentazione esadecimale ma senza '0' di padding a sinistra. In generale, per la rappresentazione in HEX di un hash dovresti generare sempre la stringa esadecimale completa tale per cui hai per ogni byte 2 cifre hex.

    SHA-1 = 160 bit = 20 byte = 40 cifre hex


    Inoltre, per non ripetere le cose (come stai facendo), fai un metodo a parte anche solo per la formattazione in hex di un byte[].
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    ok questo funziona:
    codice:
    public class ConvertHexToString {
    
        public static String convert(byte[] b) {
            StringBuilder sb = new StringBuilder(b.length * 2);
            for (int i = 0; i < b.length; i++) {
                int v = b[i] & 0xff;
                if (v < 16) {
                    sb.append('0');
                }
                sb.append(Integer.toHexString(v));
            }
            return sb.toString();
        }
    }
    però ad essere sincero nn ho capito molto il discorso generale.
    mi sa che mi devo studiare meglio la rappresentazione esadecimale.
    grazie!!

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da fermat
    codice:
        public static String convert(byte[] b) {
            StringBuilder sb = new StringBuilder(b.length * 2);
            for (int i = 0; i < b.length; i++) {
                int v = b[i] & 0xff;
                if (v < 16) {
                    sb.append('0');
                }
                sb.append(Integer.toHexString(v));
            }
            return sb.toString();
        }
    Mi pare tutto ok questo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.