Domanda Certo esperto JAVA per aiuto soluzione problema

Stato
Discussione chiusa ad ulteriori risposte.

MadJack

Bannato
11 Aprile 2014
106
17
22
74
Buonasera,
sto cercando un programmatore Java che mi possa aiutare a risolvere un problema. È prevista una ricompensa per chi riuscirà. Chi fosse interessato, mi contatti via PM.
 
Un forum lo si usa in modo "pubblico", così che chi abbia il tuo stesso problema possa benificiare della soluzione tramite il sistema di ricerca.
Non siamo su una bacheca annunci.
 
Avete ragione. In seguito cercherò di argomentare al meglio la questione. Un'app Android effettua delle richieste HTTP che hanno l'URL strutturato nel seguente modo:

Codice:
http://host?parametro1=&parametro2=parametroN=&auth=HASH

'&auth' è un parametro di controllo, in altre parole prende una parte dell'URL e ne calcola l'hash, per verificarne l'integrità e per vietare qualsiasi modifica arbitraria. Questo processo è definito nel codice sorgente.

In seguito provo a sintetizzare i passaggi più importanti:

1) Rimuove il protocollo "http://" dall'URL che viene salvato nella variabile "resultString":
Codice:
String resultString = url.replaceAll("http://", "");

2) Cerca il parametro "&auth" e salva la sua posizione nella variabile "endIndex":
Codice:
int endIndex = resultString.indexOf("&auth");

3) Aggiorna la variabile "resultString" inserendo la stringa compresa a partire dall'inizio dell'URL fino al parametro "&auth":
Codice:
resultString = resultString.substring(0, endIndex);

4) Prende il contenuto della variabile "resultString" e insieme ad un'altra variabile ne calcola l'hash che sarà (penso) successivamente aggiunta al parametro "&auth":
Codice:
return MondadoriHelpers.generate_HMAC_SHA1(resultString, privateKey);

Ho analizzato bene il sorgente? C'è qualcosa che ho sbagliato? Se avete bisogno di altre informazioni o dati, non esitate a chiedere. Grazie per le eventuali risposte.
 
Ultima modifica:
Stai sbagliando, in questo modo ottieni quasi tutto tranne che l'hash.
A patto che conosci già il length dell'hash, potresti fare una semplice sottrazione:
int beginIndex = url.length() - hashLength;
String resultString = url.substring(beginIndex, url.length());

se non sei a conoscenza del length dell'hash, è bene utilizzare lastIndexOf(), che a sua volta returna l'index del primo carattere dell'ultima sottostringa trovata.
int lastIndex = url.lastIndexOf('=');
String resultString = url.substring(lastIndex + 1, url.length());

p.s: la stringa completa 'http://' è chiamata suffisso, non protocollo.
 
Certo, intanto ti ringrazio per la risposta. Conosco addirittura tutto l'URL, quindi potrebbe risultare più semplice fare alcuni test. La lenght dell'hash è di 40 caratteri.

Codice:
http://iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=d95e6a3d094397da13f9f8b272163f67b1cc9053

Nello specifico, vorrei sapere la correlazione tra l'hash (parametro &auth) e il resto dell'URL.
 
Certo, intanto ti ringrazio per la risposta. Conosco addirittura tutto l'URL, quindi potrebbe risultare più semplice fare alcuni test. La lenght dell'hash è di 40 caratteri.

Codice:
http://iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=d95e6a3d094397da13f9f8b272163f67b1cc9053

Nello specifico, vorrei sapere la correlazione tra l'hash (parametro &auth) e il resto dell'URL.
Sì, l'ho capito. Il parametro comunque è solo auth, non &auth. Scenario: ottenere il valore del parametro 'auth', che a sua volta è l'hash. Se è questo quello che vuoi, basandomi sulla tua informazione che il length dell'hash è costante (vuol dire che che se l'hash cambierà il length sarà uguale, sei sicuro?)... La prima opzione:
int beginIndex = url.length() - 40;
String resultString = url.substring(beginIndex, url.length());

oppure semplicemente utilizzi la seconda opzione onde evitare questi problemi di cambio di length:
int lastIndex = url.lastIndexOf('=');
String resultString = url.substring(lastIndex + 1, url.length());
 
Fin qui c'ero arrivato pure io. L'obiettivo è calcolare l'hash (&auth) avendo l'URL in questo formato:
Codice:
http://iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=
...ovvero senza il valore del parametro &auth.

Secondo il sorgente dell'applicativo, i passaggi sono tre:
1) Rimuovere "http://" all'inizio, che da questo risultato:
Codice:
iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=

2) Considerare la stringa che va dall'inizio dell'URL sopracitato fino al parametro &auth, quindi precisamente:
Codice:
iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4

3) Infine, calcolare l'hash dell'URL risultante, mediante la funzione "MondadoriHelpers.generate_HMAC_SHA1".

È giusto il procedimento?
 
Ultima modifica:
Fin qui c'ero arrivato pure io. L'obiettivo è calcolare l'hash (&auth) avendo l'URL in questo formato:
Codice:
http://iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=
...ovvero senza il valore del parametro &auth.

Secondo il sorgente dell'applicativo, i passaggi sono tre:
1) Rimuovere "http://" all'inizio, che da questo risultato:
Codice:
iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=

2) Considerare la stringa che va dall'inizio dell'URL sopracitato fino al parametro &auth, quindi precisamente:
Codice:
iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4

3) Infine, calcolare l'hash dell'URL risultante, mediante la funzione "MondadoriHelpers.generate_HMAC_SHA1".

È giusto il procedimento?
Allora scusami, ho capito male io. Non era ben chiaro quello che hai chiesto.
Se vuoi ottenere questo url:
host?parametro1=&parametro2=parametroN=
allora sì, il procedimento è giusto, anche se è sbagliato utilizzare replaceAll() e non c'è bisogno di utilizzare indexOf().
Dovresti utilizzare la funzione replace() dato che vuoi solo rimuovere il suffisso (prima occorrenza), con replaceAll() sostituisci tutte le occorrenze trovate. Anche se funzionasse sarebbe solamente sbagliato.
Riguardo ad indexOf() utilizza a posto suo lastIndexOf(), è il metodo più efficiente in questo caso.

Quindi il procedimento più corretto è questo:
String resultString = url.replace("http://", "");

int lastIndex = resultString.lastIndexOf('&');
resultString = resultString.substring(0, lastIndex);

in questo modo ottieni lo stesso risultato del tuo codice. Se hai problemi quando fai la richiesta http, vuol dire che non devi lavorare in questo modo (devi lavorare in base a come vuole l'url il sito, il formato lo considera non valido). Se non funziona allora non ti posso dare più aiuto dato che non sono un indovino di come lo accetta. Non c'è una documentazione su come effettuare la richiesta in quel sito? Inoltre, una volta che lo cripti cosa devi fare?

Non sono ancora sicuro di quale sia il tuo problema. Prova.
 
Ultima modifica:
Sapendo che il protocollo è http, è sufficiente:
Java:
resultString = resultString.substring(7, url.lastIndexOf('&'));
Senza bisogno di replace().


Codice:
http://iflipit.mondadorieducation.it/sync/getEditorNotes.php?srd=&srnm=&iss=TVM1MDQ1MV8yMDE1&t=1465141330757&track_os=ios&track_osversion=9.3.2&track_device=tablet&track_uid=&track_appversion=4.3.4&auth=d95e6a3d094397da13f9f8b272163f67b1cc9053
Dato che si tratta di un hash a 40 caratteri, immagino si tratti di SHA-1. Ho provato a calcolare l'hash SHA-1 del link che hai postato in questo esempio, ma non corrisponde all'hash. Sei sicuro funzioni così?
 
Forse non sono stato abbastanza chiaro.
Non mi interessa l'implementazione in Java, quella c'è già nel sorgente. Mi interessa calcolare (non scrivetemi il codice in Java, che non mi interessa, voglio soltanto sapere che cosa fa) il parametro 'auth' in seguito ad una modifica dell'URL. Ripeto, da quanto ho potuto capire, il server di destinazione, per prevenire qualsiasi modifica arbitraria dei parametri dell'URL, ha introdotto questo parametro 'auth' che non è altro che un hash di controllo. Come questo hash sia generato è scritto nel codice, che, essendo Java, capisco poco o nulla. Per quanto riguarda la funzione generate_HMAC_SHA1, fondamentale per risolvere questa questione, questo è il sorgente dell'intero script.
 
Sapendo che il protocollo è http, è sufficiente:
Java:
resultString = resultString.substring(7, url.lastIndexOf('&'));
Senza bisogno di replace().
E in caso che il suffisso http:// sia già stato tolto? Il tuo metodo sarebbe valido a patto che l'utente dell'@OP ci informi che http:// sarà sempre presente nella stringa. Se era già tolto avresti tagliato parte di un parametro.
A quanto ho capito non è proprio questo il problema (il lavoro della stringa).
 
Forse non sono stato abbastanza chiaro.
Non mi interessa l'implementazione in Java, quella c'è già nel sorgente. Mi interessa calcolare (non scrivetemi il codice in Java, che non mi interessa, voglio soltanto sapere che cosa fa) il parametro 'auth' in seguito ad una modifica dell'URL. Ripeto, da quanto ho potuto capire, il server di destinazione, per prevenire qualsiasi modifica arbitraria dei parametri dell'URL, ha introdotto questo parametro 'auth' che non è altro che un hash di controllo. Come questo hash sia generato è scritto nel codice, che, essendo Java, capisco poco o nulla. Per quanto riguarda la funzione generate_HMAC_SHA1, fondamentale per risolvere questa questione, questo è il sorgente dell'intero script.
 
Ecco...non ci avevi dato il sorgente :\
Quel codice non calcola l'hash dell'URL, fa tutt'altro
 
Forse non sono stato abbastanza chiaro.
Non mi interessa l'implementazione in Java, quella c'è già nel sorgente. Mi interessa calcolare (non scrivetemi il codice in Java, che non mi interessa, voglio soltanto sapere che cosa fa) il parametro 'auth' in seguito ad una modifica dell'URL. Ripeto, da quanto ho potuto capire, il server di destinazione, per prevenire qualsiasi modifica arbitraria dei parametri dell'URL, ha introdotto questo parametro 'auth' che non è altro che un hash di controllo. Come questo hash sia generato è scritto nel codice, che, essendo Java, capisco poco o nulla. Per quanto riguarda la funzione generate_HMAC_SHA1, fondamentale per risolvere questa questione, questo è il sorgente dell'intero script.
Se è solo un controllo allora prova a criptare direttamente la parte senza &auth=hash e dopo gli passi l'hash al parametro auth quando esegui la richiesta http.
 
Ultima modifica:
Se è solo un controllo allora prova a criptare direttamente la parte senza &auth=hash e dopo gli passi l'hash al parametro auth quando esegui la richiesta http.

Ottimo, ci siamo! Ora non ci resta che capire come avviene la criptazione. :D

Questo il codice interessante:
Codice:
public static String generate_HMAC_SHA1(String daFirmare, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
        return binary2ASCIIHex(calcSHA1MAC(Base64.decode(secretKey, 0), daFirmare));
    }

    private static byte[] calcSHA1MAC(byte[] abyte0, String s) throws NoSuchAlgorithmException, InvalidKeyException {
        byte[] abyte1 = null;
        SecretKeySpec secretkeyspec = new SecretKeySpec(abyte0, "DES");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(secretkeyspec);
        return mac.doFinal(s.getBytes());
    }

    private static String binary2ASCIIHex(byte[] a) {
        StringBuffer buf = new StringBuffer(a.length * 2);
        for (int cx = 0; cx < a.length; cx++) {
            int ln = a[cx] & 15;
            buf.append("0123456789abcdef".charAt((a[cx] & 255) / 16));
            buf.append("0123456789abcdef".charAt(ln));
        }
        return buf.toString();
    }

Per quanto riguarda la "secretKey", penso sia una di queste:
og8WGTtmeFaZ7eNVH4EC9ueTwNx3KSKzenio9ePe2G2yHHi8NIsxmMAlsnHZiYPD
23e490b2f4daa327cc11b27e955d6573
 
Ciò che interessa sta qui:
Java:
public static String sha1Hash(String toHash) {
        String hash = null;
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(toHash.getBytes(), 0, toHash.length());
            hash = new BigInteger(1, digest.digest()).toString(16);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hash;
    }

    public static String generate_HMAC_SHA1(String daFirmare, String secretKey) throws InvalidKeyException, NoSuchAlgorithmException {
        return binary2ASCIIHex(calcSHA1MAC(Base64.decode(secretKey, 0), daFirmare));
    }

    private static byte[] calcSHA1MAC(byte[] abyte0, String s) throws NoSuchAlgorithmException, InvalidKeyException {
        byte[] abyte1 = null;
        SecretKeySpec secretkeyspec = new SecretKeySpec(abyte0, "DES");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(secretkeyspec);
        return mac.doFinal(s.getBytes());
    }

Ma queste funzioni non sono chiamate da nessuna parte in quel codice. L'algoritmo è SHA-1, non c'è molto da dire su "come viene calcolato". Semmai quello che devi vedere è cosa viene calcolato: da altre parti del codice dovresti trovare cose come `sha1Hash(qualcosa)` oppure `generate_HMAC_SHA1(qualcosa, qualcosa)`. Quei qualcosa sono ciò che può essere interessante. Tu dici che è la parte di URL senza http:// e prima di &auth... ma ne sei sicuro? Ho provato a calcolare l'hash SHA-1 dei link di esempio che hai dato, e non corrispondono.

Inoltre, se si tratta di HmacSHA-1 deve esserci anche una secrect key

(P.S.: anche io non conosco il Java - capisco giusto appena il codice solo perché è C-like)
 
Sí, la funzione di hashing viene chiamata nel sorgente principale (link). È proprio qui che si può osservare quale sia la "parte dell'URL" che sarà il primo argomento della funzione di hashing generate_HMAC_SHA1. Il secondo argomento invece, è la chiave privata, che penso sia una delle due stringhe:
og8WGTtmeFaZ7eNVH4EC9ueTwNx3KSKzenio9ePe2G2yHHi8NIsxmMAlsnHZiYPD
23e490b2f4daa327cc11b27e955d6573
 
Ottimo, ci siamo! Ora non ci resta che capire come avviene la criptazione. :D
Ho detto prova. Non è detto che il sito lo accetti di sicuro. Comunque la funzione che mi hai citato in precedenza da utilizzare per criptarlo è generate_HMAC_SHA1(), il codice completo è quello che mi hai citato tu adesso. L'algoritmo è sha1.
@SpeedJack non hai citato la funzione binary2ASCIIHex().

Sí, la funzione di hashing viene chiamata nel sorgente principale (link). È proprio qui che si può osservare quale sia la "parte dell'URL" che sarà il primo argomento della funzione di hashing generate_HMAC_SHA1. Il secondo argomento invece, è la chiave privata, che penso sia una delle due stringhe:
og8WGTtmeFaZ7eNVH4EC9ueTwNx3KSKzenio9ePe2G2yHHi8NIsxmMAlsnHZiYPD
23e490b2f4daa327cc11b27e955d6573
Ok, adesso implementa tutto tu stesso e se c'è qualcosa che non va riporta quali sono i tuoi problemi.
 
Sí, la funzione di hashing viene chiamata nel sorgente principale (link). È proprio qui che si può osservare quale sia la "parte dell'URL" che sarà il primo argomento della funzione di hashing generate_HMAC_SHA1. Il secondo argomento invece, è la chiave privata, che penso sia una delle due stringhe:
og8WGTtmeFaZ7eNVH4EC9ueTwNx3KSKzenio9ePe2G2yHHi8NIsxmMAlsnHZiYPD
23e490b2f4daa327cc11b27e955d6573
Riassumimi qual'è il problema ora che ci sono, vedo di darti una mano. Scusami se non ti ho risposto ma ho sbalzi alla connessione.
 
Riassumimi qual'è il problema ora che ci sono, vedo di darti una mano. Scusami se non ti scrivo ma ho sbalzi alla connessione.
Evitiamo ot, lui non ti deve riassumere niente, sei tu che devi leggere quello che non hai letto in questo thread per evitare doppi post di stessi/simili contenuti.
 
Ancora non riesco a ottenere l'hash giusto
Qui trovi una pagina per l'HmacSHA-1:
http://www.freeformatter.com/hmac-generator.html
Qui per fare il decode da base64 (nota che lo fa la funzione generate_HMAC_SHA1 sulla secret key):
https://www.base64decode.org/
Devi prendere un URL valido, del quale sai l'hash giusto, e trovare il modo di generarlo: quando ti esce quello giusto allora è il modo corretto.

@SpeedJack non hai citato la funzione binary2ASCIIHex().
Non l'ho citata perché è ovvia (secondo te che farà mai? lol)
 
Ripeto, non conosco il Java pertanto non saprei implimentare i due script. Questo (link) potrebbe essere lo script definitivo, confermatemi se funziona (non ho installato JVM eccetera):

Edit: Lo script non funziona perché ho dimenticato di definire la variabile 'resultString'. Qui lo script definitivo e corretto (link).

L'output dovrebbe essere 'd95e6a3d094397da13f9f8b272163f67b1cc9053'.
 
Ultima modifica:
Non l'ho citata perché è ovvia (secondo te che farà mai? lol)
Non c'entra se è ovvio o meno, si dovevano elencare tutte le funzioni da usare. (Non ho citato generate_HMAC_SHA1() perchè è ovvia, secondo te che farà mai?) x'D. L'importante è il contenuto.

Ora faccio dei test con quel sito.

@MadJack non vuol dire che se non sai il Java il codice te lo devono scrivere gli altri. Manca qualche funzione e altro.
 
Stato
Discussione chiusa ad ulteriori risposte.