Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16
  1. #1

    Creare una classe disponibile in una Servlet

    Vorrei creare una classe per convertire le password in md5. Perché questo codice non funziona?
    Come si deve editare?
    Tra questi 3 qual è il migliore?
    https://docs.oracle.com/javase/10/do...ageDigest.html
    grazie

    codice:
    package web1;
    
    import java.math.BigInteger;
    import java.security.MessageDigest;
    
    public class FromStringToMD5 {
        private String code;
        private String precode;
        private StringBuilder sb;
        private String hashtext;
        private void FromStringToMD5(String code, String precode){
            this.code = code;
            this.precode = precode;
        }
    private void testStringBuilder() {
            sb = new StringBuilder("");
            sb.append(this.code);
            sb.append(this.precode);
        }
    MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        byte[] messageDigest = md.digest(sb.getBytes());
        BigInteger number = new BigInteger(1, messageDigest);
        hashtext = number.toString(16);
        return hashtext;
    }
    Più pratica in futuro...

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Vorrei creare una classe per convertire le password in md5.
    Ci sono alcuni aspetti che non hai considerato. Quando si converte una stringa nella sequenza di byte, bisogna SEMPRE tenere in considerazione il charset da usare. Il getBytes() (senza argomenti) usa il charset di default della piattaforma, che potrebbe essere appropriato oppure no. E questo, tra l'altro, vorrebbe dire che da una piattaforma all'altra avresti hash diversi dalla stessa stringa!!

    In questi casi è sempre bene specificare il charset: getBytes("UTF-8")

    Come seconda cosa, il toString(16) (per l'esadecimale) non è sbagliato ma non ti dà gli 0 "non significativi" all'inizio.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Perché questo codice non funziona?
    Hai messo del codice (quel try-catch e quello dopo) fuori da un metodo, al livello della classe. Non ti compila proprio! Perlomeno per come si legge sopra.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Tra questi 3 qual è il migliore?
    Intendi quale algoritmo di hashing è meglio? Più è lungo il digest (in bit) e generalmente meglio è. Il MD5 è già stato "bucato" dai ricercatori. SHA-1 ora non ricordo. La questione è: a cosa serve l'hash a te.

    Se puoi usare almeno Java 9, ci sono anche i nuovi SHA3-224, SHA3-256, SHA3-384 e SHA3-512.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  3. #3
    Hai ragione, scusa ma ero a digiuno di programmazione. Ho corretto ora la classe. A tuo avviso ora il codice è perfetto?

    codice:
    package web1;
    
    import java.math.BigInteger;
    import java.security.MessageDigest;
    
    public class FromStringToMD5 {
    
        private String Code;
        private String PreCode;
        private String HashText;
    
        private void FromStringToMD5(String Code, String PreCode){
            this.Code = Code;
            this.PreCode = PreCode;
        }
    
        private String HashConvert(String Password) {
            try {
                MessageDigest md = MessageDigest.getInstance("SHA3-512");
                byte[] messageDigest = md.digest(Password.getBytes("UTF-8"));
                BigInteger number = new BigInteger(1, messageDigest);
                String HashPassword = number.toString();
                return HashPassword;
            } catch (Exception e){
                return null;
            }
        }
        
        private String CombineString() {
            try {
                StringBuilder sb = new StringBuilder("");
                sb.append(this.Code);
                sb.append(this.PreCode);
                return sb.toString();
            }catch(Exception e){
                return null;
            }
        }
        
        private String getHashText() {
            try {
                String Text = CombineString();
                HashText = HashConvert(HashConvert(Text));
                return HashText;
            } catch (Exception e){
                return null;
            }
        }
    
    }
    Non capisco a cosa serva quel 1 e cosa devo mettere al posto di 16, inoltre con mi è chiaro al 100% il metodo HashConvert.

    Grazie per l'aiuto.
    Più pratica in futuro...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    A tuo avviso ora il codice è perfetto?
    Perfetto proprio no! Ci sono svariate cose che non sono particolarmente buone (es. il catch che ritorna null).
    Ma poi scusa ... che te ne fai di una classe che ha tutto private e nessun metodo "pubblico" ??
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Il "minimo" per fare la cosa corretta e un pochino pulita (ma si potrebbe fare ancora meglio!) può essere questo, scritto e provato al volo:

    codice:
    public class DigestUtils {
        private DigestUtils() {}
    
        public static String md5Hex(String str) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(utf8Bytes(str));
            BigInteger number = new BigInteger(1, digest);
            return String.format("%032x", number);
        }
    
        private static byte[] utf8Bytes(String str) {
            try {
                return str.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new Error("Grave error, UTF-8 not supported!");
            }
        }
    }
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  6. #6
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Perfetto proprio no! Ci sono svariate cose che non sono particolarmente buone (es. il catch che ritorna null).
    Ma poi scusa ... che te ne fai di una classe che ha tutto private e nessun metodo "pubblico" ??
    Se il codice dovesse intopparsi o qualcuno dovesse farlo intoppare apposta con null non sarebbe possibile risalire alla causa dell'intoppo. Quando si tenta di acherare la prima cosa che si fa è mandare in eccezione il programma. Studiando le eccezioni si possono sapere informazioni relative alla classe. Se getInstance() non richiedesse try/catch non userei la gestione delle eccezioni.
    Hai ragione sul discorso dei metodi, devo mettere public per poterli usare.
    Voglio che nel file in cui vado a salvare le password degli utenti queste ultime non siano visibili in chiaro.
    Più pratica in futuro...

  7. #7
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Il "minimo" per fare la cosa corretta e un pochino pulita (ma si potrebbe fare ancora meglio!) può essere questo, scritto e provato al volo:

    codice:
    public class DigestUtils {
        private DigestUtils() {}
    
        public static String md5Hex(String str) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(utf8Bytes(str));
            BigInteger number = new BigInteger(1, digest);
            return String.format("%032x", number);
        }
    
        private static byte[] utf8Bytes(String str) {
            try {
                return str.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new Error("Grave error, UTF-8 not supported!");
            }
        }
    }
    Cosa significa “%032x”?
    Cosa significa “1”? Perché semplicemente non “BigInteger(digest)”?
    Si converte tutto in Byte perché digest() vuole così, giusto?
    Più pratica in futuro...

  8. #8
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Il "minimo" per fare la cosa corretta e un pochino pulita (ma si potrebbe fare ancora meglio!) può essere questo, scritto e provato al volo:

    codice:
    public class DigestUtils {
        private DigestUtils() {}
    
        public static String md5Hex(String str) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(utf8Bytes(str));
            BigInteger number = new BigInteger(1, digest);
            return String.format("%032x", number);
        }
    
        private static byte[] utf8Bytes(String str) {
            try {
                return str.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new Error("Grave error, UTF-8 not supported!");
            }
        }
    }
    Cosa significa “%032x”?
    Cosa significa “1”?
    Perché semplicemente non “BigInteger(digest)”?
    Si converte tutto in Byte perché digest() vuole così, giusto?
    Farei questa modifica:
    codice:
    package web1;
    
    import java.io.UnsupportedEncodingException;
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class FromStringToHash {
    
        private String Code;
        private String PreCode;
        private String HashText;
    
        public void FromStringToHash(String Code, String PreCode){
            this.Code = Code;
            this.PreCode = PreCode;
        }
    
        public void FromStringToHash(String Code){
            this.Code = Code;
            this.PreCode = "";
        }
    
        public static String hashConvert(String Password, String HashFunction) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance(HashFunction);
            byte[] digest = md.digest(utf8Bytes(Password));
            BigInteger number = new BigInteger(1, digest);
            return String.format("%032x", number);
        }
    
        private static byte[] utf8Bytes(String str) {
            try {
                return str.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new Error("Errore grave, UTF-8 non supportato!");
            }
        }
    
        public String combineString(String a, String b) {
            try {
                StringBuilder sb = new StringBuilder("");
                sb.append(a);
                sb.append(b);
                return sb.toString();
            }catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    
        public String getHashText() {
            try {
                if(this.PreCode.equals("")){
                    // Vecchie versioni di Tomcat
    String HF = "MD5";
                    HashText = hashConvert(this.Code, HF);
                    return HashText;
                }else{
                    // Nuove versioni di Tomcat
    String HF = "SHA3-512";
                    HashText = hashConvert(combineString(hashConvert(this.Code,HF), hashConvert(this.PreCode,HF)),HF);
                    return HashText;
                }
            } catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    
    }
    Per fare una cosa bella bisognerebbe che lo script calcolasse in automatico il sistema di conversione più evoluto del container ed usasse quello ma non saprei come fare (su IntelliJ ho java 1.10, sul server non posso saperlo). Tu sei in grado?
    Ultima modifica di giannino1995; 08-08-2018 a 19:07
    Più pratica in futuro...

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,254
    Allora, un po' di questioni, vediamo di andare con ordine:

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Se getInstance() non richiedesse try/catch non userei la gestione delle eccezioni.
    Il getInstance() riceve una stringa con il nome dell'algoritmo. Il nome potrebbe essere "sballato" (es. "MDD5", se fosse un input preso da qualche parte) oppure potrebbe essere sensato ma non supportato su una certa versione della piattaforma Java. Il getInstance segnala la cosa con un NoSuchAlgorithmException, che purtroppo è una eccezione "checked", quindi il programmatore non la può ignorare.

    Nel mio esempio "basilare" ho fatto semplicemente uscire NoSuchAlgorithmException dal md5Hex. Ma ci sono diverse varianti che possono aver senso:

    1) Nel md5Hex() far uscire NoSuchAlgorithmException (come ho fatto)
    2) Nel md5Hex() catturare NoSuchAlgorithmException per fare del "logging" e poi rilanciare fuori dal md5Hex il NoSuchAlgorithmException così come è.
    3) Nel md5Hex() catturare NoSuchAlgorithmException (con/senza logging) e lanciare fuori un'altra eccezione differente magari "unchecked" in modo che il programmatore possa non doversene preoccupare subito.

    Ma catturare NoSuchAlgorithmException e fare un return null, no, ha davvero poco senso.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Cosa significa “%032x”?
    E' una stringa di "formato" utilizzata dalla funzionalità di "formattazione delle stringhe" che è stata introdotta in Java 5. Documentati perché è una cosa molto utile in generale.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Cosa significa “1”? Perché semplicemente non “BigInteger(digest)”?
    La documentazione di BigInteger è chiara:

    BigInteger(int signum, byte[] magnitude)

    signum - signum of the number (-1 for negative, 0 for zero, 1 for positive).
    magnitude - big-endian binary representation of the magnitude of the number.
    Il digest lo passiamo al BigInteger che lo tratterà come un numero di tot byte (bit x 8) ma con il solo scopo poi di formattarlo in hex (non ci interessa farci calcoli!). Ma il digest NON è un numero (in senso stretto, specifico), è solo un tot di byte "crudi". Quindi con 1 indichiamo al BigInteger di trattarlo come numero positivo, perché non ci interessa altro modo.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Si converte tutto in Byte perché digest() vuole così, giusto?
    Il risultato di un algoritmo di hash è un tot di bit "crudi", che non hanno alcun significato particolare, a parte appunto rappresentare una sorta di "firma" di un messaggio di tot byte.
    Quindi il MessageDigest dà il risultato come array di byte. Non offre alcun supporto alla "formattazione". Come formattarlo in stringa (tipicamente in hex ma in rari casi in Base64 o altro) è compito nostro.

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Per fare una cosa bella bisognerebbe che lo script calcolasse in automatico il sistema di conversione più evoluto del container ed usasse quello
    Prima hai detto, quoto:

    Quote Originariamente inviata da giannino1995 Visualizza il messaggio
    Voglio che nel file in cui vado a salvare le password degli utenti queste ultime non siano visibili in chiaro.
    Se vuoi fare un file (o DB) con delle password NON in chiaro, allora un hash è ok. Ma l'algoritmo di hashing lo devi stabilire TU a priori. Non è una cosa che puoi far scegliere ad una macchina, non ha senso!

    La API della security (package java.security) permette di scoprire dinamicamente tutti i servizi (compresi quelli di message digest) di un certo provider. Quindi puoi prendere l'elenco dei Provider, per ciascuno l'elenco dei service e filtrarli per trovare tutti gli algoritmi di digest disponibili. Se vuoi del codice, non c'è problema. Per ciascun MessageDigest puoi anche sapere la lunghezza del digest (metodo getDigestLength() ).

    Ma il punto è che per fare quello che hai detto, l'algoritmo lo devi scegliere e imporre TU, non lo può fare una macchina. Non puoi determinare programmaticamente quale algoritmo è il "migliore". La conoscenza anche basilare sulle caratteristiche degli algoritmi la devi avere tu ... non la macchina!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    Java Versions Cheat Sheet

  10. #10
    Sempre Grazie, Ho trovato la pagina:
    https://docs.oracle.com/javase/6/doc...Formatter.html
    %: è il simbolo che precede il codice usato per la formattazione delle stringhe; 0: riempie il numero con degli zeri iniziali se le cifre del numero sono inferiori a 32;
    32: il numero deve essere formato da 32 cifre;
    x: x minuscola indica che il numero da convertire in stringa è un numero in base 16;
    (un numero in base 16 è formato dalle cifre 0-9 più le lettere a-f oppure dalle relative maiuscole A-F)
    Non mi è chiaro cosa accade se il numero è più lungo di 32 cifre: vengono prese le prime 32 lettere, le ultime oppure viene lanciata un’eccezione?
    Se uso “SHA3-512” la stringa di formattazione sarebbe “%0128x”, giusto? Non c’è una tabella su internet che per ogni hash definisce la relativa stringa da inserire in format? Non vorrei fare errori sciocchi come questo. Il primo parametro di public BigInteger(int signum, byte[] magnitude) indica il segno del numero: -1: il numero è negativo; 0: il numero è nullo; +1: il numero è positivo; Direi che 1 è il numero gusto da inserire. Hai ragione sugli algoritmi, ho scritto senza ragionare. Devo però prestare attenzione a quando vado online perché posso rischiare di avere un’applicazione che non funziona e non scoprirne le ragioni. Vorrei usare SHA3-512 ma dovrei aggiungere al codice un avviso che informa l’utente sul sistema di conversione disponibile sul container. Esiste una pagina sul web che definisce gli hash compatibili con i diversi server Tomcat. Una nota a margine: il container e Tomcat sono la stessa cosa? Il mio linguaggio è giusto?
    Il resto che hai scritto è chiaro.
    ciao
    P.S.: Questo codice a tuo avviso è accettabile?
    codice:
    package web1;
    import java.io.UnsupportedEncodingException;
    import java.math.BigInteger;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    public class FromStringToHash {
    private String Code;
    private String PreCode;
    private String HashText;public void FromStringToHash(String Code, String PreCode){
            this.Code = Code;
            this.PreCode = PreCode;
        }
    public void FromStringToHash(String Code){
            this.Code = Code;
            this.PreCode = "";
        }
    public static String hashConvert(String Password, String HashFunction) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance(HashFunction);
            byte[] digest = md.digest(utf8Bytes(Password));
            BigInteger number = new BigInteger(1, digest);
            return String.format("%0128x", number);
        }
    private static byte[] utf8Bytes(String str) {
            try {
                return str.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new Error("Errore grave, UTF-8 non supportato!");
            }
        }
    public String combineString(String a, String b) {
            try {
                StringBuilder sb = new StringBuilder("");
                sb.append(a);
                sb.append(b);
                return sb.toString();
            }catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    public String getHashText() {
            try {
                String HF = "SHA3-512";
                HashText = hashConvert(combineString(hashConvert(this.Code,HF), hashConvert(this.PreCode,HF)),HF);
                return HashText;
            } catch (Exception e){
                throw new Error("SHA3-512 non supportato. Scegli una funzione hash compatibile con la versione in uso di Tomcat.");
            }
        }
    }
    Ho come l'impressione che quando tu legga il mio codice faccia questa smorfia:
    Ultima modifica di giannino1995; 09-08-2018 a 16:57
    Più pratica in futuro...

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 © 2024 vBulletin Solutions, Inc. All rights reserved.