2012-05-22 5 views
30

Qualcuno mi può mostrare un esempio di lavoro di come generare un hash SHA di una stringa che ho, diciamo myPassword := "beautiful", utilizzando Go 1?Generare l'hash SHA di una stringa utilizzando golang

Le pagine docs mancano esempi e non sono riuscito a trovare alcun codice di lavoro su Google.

+6

Se la password hashing è in realtà quello che sei facendo, non dovresti usare SHA1 nudo per questo - usa PBKDF2, SCRYPT o BCRYPT. –

+0

Sì, mi piacerebbe fare tutto ciò. Ma golang non supporta nessuno di loro in modo nativo e non voglio fare affidamento su librerie di terze parti. –

+0

Quindi utilizzare Sha256. E non aver troppa paura: anche se ora si sa che sha1 non è teoricamente così forte come inizialmente pensavamo, un attacco brutale è ancora quasi impossibile. Non dimenticare di aggiungere un sale, però, per proteggere il tuo utente per le ricerche nel database. Con SHA 256 e un sale, sei a posto. –

risposta

45

Un esempio:

import (
    "crypto/sha1" 
    "encoding/base64" 
) 

func (ms *MapServer) storee(bv []byte) { 
    hasher := sha1.New() 
    hasher.Write(bv) 
    sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) 
     ... 
} 

In questo esempio faccio una sha da un array di byte. È possibile ottenere l'array di byte utilizzando

bv := []byte(myPassword) 

Naturalmente non è necessario codificare in base64 se non si deve: si può utilizzare l'array di byte grezzo restituita dalla funzione Sum.

Sembra che ci sia un po 'po' di confusione nei commenti qui sotto. Quindi cerchiamo di chiarire per i prossimi agli utenti le migliori pratiche in materia di conversioni per le stringhe:

  • mai memorizzare una SHA come una stringa in un database, ma come byte prime
  • quando si desidera visualizzare uno SHA a un utente, un modo comune è Hexadecimal
  • quando si vuole una rappresentazione di stringa perché deve inserirsi in un URL o in un nome di file, la soluzione più comune è Base64, che è più compatto
+10

Il solito modo di rappresentare uno sha come stringa è la codifica esadecimale non base64. –

+1

Dipende dalle tue necessità. La codifica esadecimale è buona per gli umani ma anche più pesante di base64. Se vuoi memorizzare il tuo hash in un db, o inviarlo in json, o usarlo come nome di file (come nel mio esempio), penso che base64 sia migliore. –

27

la documentazione del pacchetto a http://golang.org/pkg/crypto/sha1/ ha un esempio t lo dimostra. È indicato come un esempio della nuova funzione, ma è l'unico esempio nella pagina e ha un collegamento vicino alla parte superiore della pagina, quindi vale la pena guardare. L'esempio completo è,

Codice:

h := sha1.New() 
io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") 
fmt.Printf("% x", h.Sum(nil)) 

uscita:

59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd

+2

Lo fa. Sembra che sia così difficile da trovare con così tante parti nascoste. Problema di usabilità –

+2

@SankarP: Per ora, soprattutto se non si programma in Go ogni giorno, è un po 'difficile capire come utilizzare l'API. Ho trovato più facile leggere il codice sorgente API (che è generalmente semplice). Sarà probabilmente più semplice con il tempo e più esempi e documenti di terze parti online. –

+1

@SankarP: prova [godock.org] (http://godock.org) per semplificare la navigazione delle API della libreria standard. – Isaiah

4

Ecco alcuni buoni esempi:

Il secondo esempio rivolge sha256, fare SHA1 esadecimale faresti:

// Calculate the hexadecimal HMAC SHA1 of requestDate using sKey     
key := []byte(c.SKey)               
h := hmac.New(sha1.New, key)              
h.Write([]byte(requestDate))              
hmacString := hex.EncodeToString(h.Sum(nil)) 

(da https://github.com/soniah/dnsmadeeasy)

18

Go By Example ha una pagina su sha1 shahing.

package main 

import (
    "fmt" 
    "crypto/sha1" 
    "encoding/hex" 
) 

func main() { 

    s := "sha1 this string" 
    h := sha1.New() 
    h.Write([]byte(s)) 
    sha1_hash := hex.EncodeToString(h.Sum(nil)) 

    fmt.Println(s, sha1_hash) 
} 

È possibile run this example on play.golang.org

12

si può effettivamente fare questo in un modo molto più conciso e idiomatica:

// Assuming 'r' is set to some inbound net/http request 
form_value := []byte(r.PostFormValue("login_password")) 
sha1_hash := fmt.Sprintf("%x", sha1.Sum(form_value)) 

// Then output optionally, to test 
fmt.Println(sha1_hash) 

In questo esempio banale di un POST http.Request contenente un campo login_password, è vale la pena notare che fmt.Sprintf() chiamato con %x ha convertito il valore hash in hex senza dover includere una dichiarazione import "encoding/hex".

(Abbiamo usato fmt.Sprintf() anziché fmt.Printf() come ci hanno emettere una stringa di un'assegnazione variabile, non un'interfaccia io.Writer.)

Anche di riferimento, è che la funzione sha1.Sum() un'istanza verbosely nello stesso modo del sha1.New() definizione:

func New() hash.Hash { 
    d := new(digest) 
    d.Reset() 
    return d 
} 

func Sum(data []byte) [Size]byte { 
    var d digest 
    d.Reset() 
    d.Write(data) 
    return d.checkSum() 
} 

Questo vale (almeno al momento del distacco) per le varianti della biblioteca Sha nel set standard di crittografia di Golang, come ad esempio Sha512.

Infine, se si desidera, potrebbero seguire l'implementazione [di] String() di Golang con qualcosa come func (h hash.Hash) String() string {...} per incapsulare il processo.

Questo è molto probabilmente oltre lo scopo desiderato della domanda originale.

+0

Grazie per tutti i dettagli in più Mr. Webster! –

2

Ecco una funzione è possibile utilizzare per generare un hash SHA1:

// SHA1 hashes using sha1 algorithm 
func SHA1(text string) string { 
    algorithm := sha1.New() 
    algorithm.Write([]byte(text)) 
    return hex.EncodeToString(algorithm.Sum(nil)) 
} 

ho messo insieme un gruppo di quelle funzioni di utilità hash qui: https://github.com/shomali11/util

Troverete FNV32, FNV32a, FNV64, FNV65a, MD5, SHA1, SHA256 e SHA512

Problemi correlati