2015-07-02 19 views
6

Ho eseguito due SHA1 in codice C, uno per una stringa e un altro per un intero e ottenere risultati diversi.Python SHA1 Numero intero

SHA_init(&ctx); 
SHA_update(&ctx, "1234", 4); 
sha = SHA_final(&ctx); 

unsigned n = 1234; 
SHA_init(&ctx); 
SHA_update(&ctx, &n, sizeof(n)); 
sha = SHA_final(&ctx); 

string result: 7110eda4d09e62aa5e4a390b0a572acd2c220 
integer result: c7f07b846cc46631c2079cdd7179afdd783d643 

in python, è molto facile ottenere lo SHA1 stringa

sha1 = hashlib.sha1() 
sha1.update('1234') 
sha1.hexdigest() 

'7110eda4d09e062aa5e4a390b0a572ac0d2c0220' 

Possiamo vedere il risultato della stringa è lo stesso codice C. Ma come ottenere l'intero SHA1 in python? perché il python sha1 non supporta l'intero.

Ho provato il seguente codice, ma non è possibile ottenere lo stesso risultato del codice C.

aint = unpack('>4B', pack('>I', 1234)) 
sha1 = hashlib.sha1() 
sha1.update(bytearray(aint)) 
sha1.hexdigest() 

'ac9928e78cf6ea117451ecd6654fea2adae73e21'

come fare la SHA1 intero in Python?

+0

Suggerimento: 'map (ord," 1234 ") == [49, 50, 51, 52]! = [210, 4] == [1234 & 0xff, 1234 >> 8]' – kay

+0

Che ne dici di 'sha1.aggiornamento (str (1234)) '? – ycsun

+0

Ovviamente, 'sha1.update (str (1234))' è uguale a 'sha1.update ('1234')' –

risposta

2

Non riesco a riprodurre i risultati in C, quale libreria SHA stai utilizzando? OpenSSL raccomanda le funzioni SHA1_* ma dice che SHA_* sono inclusi per la compatibilità. Questi due danno risultati diversi per me, quindi se si sta confrontando per Pythons SHA1, si dovrebbe utilizzare SHA1_*

#include <openssl/sha.h> 
#include <stdio.h> 

int main(void) { 
    unsigned n = 1234; 
    unsigned char md[50]; 
    SHA_CTX c; 

    for (int i=0; i<sizeof(n); i++) { 
     printf("%02x ", ((unsigned char*)&n)[i]); 
    } 
    printf("\n"); 

    SHA1_Init(&c); 
    SHA1_Update(&c, &n, 4); 
    SHA1_Final(md, &c); 

    for (int i=0; i<20; i++) { 
     printf("%02x", md[i]); 
    } 
    printf("\n"); 
    return 0; 
} 

Dà:

d2 04 00 00 
7b08e025e311c3dfcf5179b67c0fdc08e73de261 

che suggerisce che sei imballaggio byte dalla parte del torto ordine nella tua implementazione python. Dovrebbe essere:

>>> import hashlib 
>>> hashlib.sha1(b'\xd2\x04\x00\x00').hexdigest() 
'7b08e025e311c3dfcf5179b67c0fdc08e73de261' 
>>> hashlib.sha1(bytearray(unpack('>4B', pack('I', 1234)))).hexdigest() 
'7b08e025e311c3dfcf5179b67c0fdc08e73de261' 

(Nota n > davanti al I), che corrisponde al shasum sopra.

Per avere un riferimento, se uso le SHA_* funzioni ottengo

int main(void) { 
    unsigned n = 1234; 
    unsigned char md[50]; 
    SHA_CTX c; 

    SHA_Init(&c); 
    SHA_Update(&c, &n, 4); 
    SHA_Final(md, &c); 

    for (int i=0; i<20; i++) { 
     printf("%02x", md[i]); 
    } 
    printf("\n"); 
    return 0; 
} 

3e491ac1d065d6d666e5e216e0cddf60fcb5be86 

Quale sembra essere d'accordo con il CSA ("SHA-0") Valore in Python:

>>> hashlib.new('sha', b'\xd2\x04\x00\x00').hexdigest() 
'3e491ac1d065d6d666e5e216e0cddf60fcb5be86' 
+0

Grazie per la risposta. Ho usato lo SHA dal codice Android. https://github.com/android/platform_system_core/blob/master/libmincrypt/sha.c. Ma è strano che la stringa SHA sia abbinata. –

+0

E 'hashlib.sha1 (bytearray (unpack ('> 4B', pack ('I', 1234))). Hexdigest()' è la funzione giusta per fare l'integratore in python? Grazie. –

1

Può essere il codice che converte in esadecimale per la stampa. Nota come nessuno dei tuoi hash è lungo 40 caratteri? Prova a utilizzare il mio metodo to_hex() di seguito.

python ==> '7110eda4d09e062aa5e4a390b0a572ac0d2c0220' 
string result: 7110eda4d09e62aa5e4a390b0a572acd2c220 
integer result: c7f07b846cc46631c2079cdd7179afdd783d643 

Inoltre, non è stato possibile riprodurre i risultati C. Ecco una versione OSX:

#include <stdio.h> 
#include <CommonCrypto/CommonDigest.h> 

char *to_hex(unsigned char *buffer, size_t len) { 
    static char out[100]; 
    char *p = out; 
    while (len--) 
    p += sprintf(p, "%02x", *buffer++); 
    *p = 0; 
    return out; 
} 

int main() { 
    unsigned char buffer[21] = { 0 }; 
    printf("SHA1(\"1234\") = %s\n", to_hex(CC_SHA1("1234", 4, buffer), 20)); 

    unsigned n = 1234; 
    printf("1234 LE =  %s\n", to_hex(&n, 4)); 
    printf("SHA1(1234 LE) = %s\n", to_hex(CC_SHA1(&n, 4, buffer), 20)); 

    n = htonl(n); 
    printf("1234 BE =  %s\n", to_hex(&n, 4)); 
    printf("SHA1(1234 BE) = %s\n", to_hex(CC_SHA1(&n, 4, buffer), 20)); 

    return 0; 
} 

ed ecco la versione di Android

#include <stdio.h> 
#include "mincrypt/sha.h" 

char *to_hex(unsigned char *buffer, size_t len) { 
    static char out[100]; 
    char *p = out; 
    while (len--) 
    p += sprintf(p, "%02x", *buffer++); 
    *p = 0; 
    return out; 
} 

int main() { 
    unsigned char buffer[21] = { 0 }; 
    printf("SHA1(\"1234\") = %s\n", to_hex(SHA1_hash("1234", 4, buffer), 20)); 

    unsigned n = 1234; 
    printf("1234 LE =  %s\n", to_hex(&n, 4)); 
    printf("SHA1(1234 LE) = %s\n", to_hex(SHA1_hash(&n, 4, buffer), 20)); 

    n = htonl(n); 
    printf("1234 BE =  %s\n", to_hex(&n, 4)); 
    printf("SHA1(1234 BE) = %s\n", to_hex(SHA1_hash(&n, 4, buffer), 20)); 

    return 0; 
} 

che file è in system/core/libmincrypt e compilato con cc -I../include -o sha_test sha_test.c sha.c

entrambi i programmi producono gli stessi risultati

SHA1("1234") = 7110eda4d09e062aa5e4a390b0a572ac0d2c0220 
1234 LE =  d2040000 
SHA1(1234 LE) = 7b08e025e311c3dfcf5179b67c0fdc08e73de261 
1234 BE =  000004d2 
SHA1(1234 BE) = ac9928e78cf6ea117451ecd6654fea2adae73e21 
+1

Spiacente, il mio codice di test ha qualche problema, la n è cambiata. Dopo aver corretto questo errore, lo SHA è allineato al codice C. Grazie a tutti voi –

2
digest = sha1.hexdigest() 
digest_int = int(digest,16) 
+0

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo su come e/o perché risolve il problema migliorerebbe il valore a lungo termine della risposta. –