2012-05-22 48 views
30

¿Puede alguien mostrarme un ejemplo práctico de cómo generar un hash SHA de una cadena que tengo, digamos myPassword := "beautiful", usando Go 1?Generar el hash SHA de una cadena usando golang

Las páginas de documentos carecen de ejemplos y no pude encontrar ningún código que funcione en Google.

+6

Si la contraseña es lo que realmente eres haciendo, no debería usar SHA1 desnudo para esto - use PBKDF2, SCRYPT o BCRYPT. –

+0

Sí, me gustaría hacer algo de eso. Pero golang no admite ninguno de ellos de forma nativa y no quiero depender de bibliotecas de terceros. –

+0

Así que use Sha256. Y no tengas miedo: incluso si ahora se sabe que sha1 teóricamente no es tan fuerte como inicialmente pensamos que era, un ataque bruto es casi imposible. No olvide agregar una sal, para proteger a su usuario de las búsquedas en la base de datos. Con SHA 256 y una sal, estás bien. –

Respuesta

45

Un ejemplo:

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

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

En este ejemplo voy a hacer un sha de una matriz de bytes. Usted puede obtener el conjunto de bytes con

bv := []byte(myPassword) 

Por supuesto que no es necesario para codificar en base 64 si usted no tiene que: es posible utilizar la matriz de bytes en bruto devuelto por la función Suma.

Parece haber algo de confusión en los comentarios a continuación. Así que vamos a aclarar para los próximos usuarios de las mejores prácticas en las conversiones de cadenas:

  • nunca almacenar una SHA como una cadena en una base de datos, pero como bytes prima
  • cuando se quiere mostrar un SHA a un usuario, una forma común es Hexadecimal
  • cuando se desea una representación de cadena, ya que debe caber en una URL o un nombre de archivo, la solución habitual es Base64, que es más compacto
+10

La forma habitual de representar un sha como cadena es la codificación hexadecimal no base64. –

+1

Depende de su necesidad. La codificación hexadecimal es buena para los humanos pero incluso más pesada que la base64. Si desea almacenar su hash en un db, o enviarlo en json, o usarlo como un nombre de archivo (como en mi ejemplo), creo que base64 es mejor. –

27

el paquete de documentación en http://golang.org/pkg/crypto/sha1/ sí tiene una ejemplo tha t demuestra esto. Se indica como un ejemplo de la función Nueva, pero es el único ejemplo en la página y tiene un enlace justo cerca de la parte superior de la página, por lo que vale la pena mirarlo. El ejemplo completo es,

Código:

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

de salida:

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

+2

Sí. Parece que es tan difícil de encontrar con tantas partes ocultas. Problema de usabilidad –

+2

@SankarP: por ahora, especialmente si no programa en Go todos los días, es un poco difícil de entender cómo usar la API. Me resultó más fácil leer el código fuente de la API (que generalmente es simple). Probablemente será más fácil con el tiempo y más ejemplos y documentos de terceros en línea. –

+1

@SankarP: Pruebe [godock.org] (http://godock.org) para una navegación api de biblioteca estándar más fácil. – Isaiah

4

Aquí hay algunos buenos ejemplos:

El segundo ejemplo sha256 objetivos, hacer hexadecimal sha1 que haría:

// 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)) 

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

18

Go By Example tiene una página en sha1 hash

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) 
} 

Puede run this example on play.golang.org

12

En realidad se puede hacer esto de una manera mucho más concisa e idiomático:

// 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) 

En este ejemplo trivial de un puesto http.Request que contiene un campo login_password, es vale la pena señalar que fmt.Sprintf() llamado con %x convirtió el valor hash a hexadecimal sin tener que incluir una declaración import "encoding/hex".

(utilizamos fmt.Sprintf() en contraposición a fmt.Printf() como estábamos la salida de una cadena a una asignación de variable, no una interfaz io.Writer.)

también de referencia, es decir que la función sha1.Sum() instancia más detallados de la misma manera como el sha1.New() definición:

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() 
} 

Esto es cierto (al menos en el momento de la publicación) para las variantes de la biblioteca Sha en conjunto estándar de cifrado de Golang, como Sha512.

Por último, si uno quisiera, podrían seguir la implementación de Golang [to] String() con algo como func (h hash.Hash) String() string {...} para encapsular el proceso.

Eso es muy probablemente más allá del alcance deseado de la pregunta original.

+0

¡Gracias por todos los detalles, Sr. Webster! –

2

Aquí es una función que podría utilizar para generar 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)) 
} 

Monté un grupo de esas funciones hash utilidad aquí: https://github.com/shomali11/util

Encontrará FNV32, FNV32a, FNV64, FNV65a, MD5, SHA1, SHA256 y SHA512

Cuestiones relacionadas