2009-08-02 18 views
7

Necesito una función segura (criptografía) hash con las siguientes propiedades:simple (con el código) la función hash seguro

  1. puede ser codificado en tan pocas líneas como sea posible (en R5RS Scheme). Esperanzadamente debajo de 50.
  2. Memoria y funcionamiento de la CPU dentro de la razón para los datos de la longitud de la contraseña. (por ejemplo, no tiene que ser súper eficiente o crear hashes para millones de bytes de datos)

Las funciones hash más seguras que puedo encontrar están diseñadas teniendo en cuenta la velocidad/la eficiencia de la memoria y son complejas para codificar como resultado .

El candidato actual es Mash-1 (o Mash-2): Handbook of applied cryptography. Google Books

Gracias.

Edit: Gracias a todos por sus respuestas hasta el momento. Por favor, perdónenme si lo siguiente es grosero, solo quiero ser claro. Por favor, créame que hice mi tarea y consideré las opciones "estándar". Sé que lo más fácil es usar uno de esos, pero eso no es lo que estoy buscando.

La única pregunta que intento responder es: ¿Qué algoritmo hash criptográficamente seguro se puede implementar en la menor cantidad de código "legible"?

Ya he publicado el mejor candidato que pude encontrar. Cualquier sugerencia sobre algo más simple, o comentario sobre Mash-1/2 sería de gran ayuda.

+3

¿Estás haciendo esto como un ejercicio de aprendizaje porque francamente no confiaría en nada además de los algoritmos comúnmente conocidos. –

+0

El problema que tienes es que nadie está dispuesto a poner su mano en su corazón y decir "X es seguro" cuando X es un primitivo criptogénico poco estudiado. Esto se debe a que "seguro" generalmente significa "no se ha roto aún, a pesar de la atención significativa". – caf

+0

Realmente necesita aclarar sus requisitos de seguridad: si no elige uno de los algoritmos hash más comunes, está realizando una transacción de seguridad, ya que es mucho más probable que tenga una debilidad desconocida. "Seguro" no es un valor binario. No está dispuesto a usar SHA-512 porque es demasiado complejo de implementar. Así que ayúdanos a descubrir cuánta seguridad estás dispuesto a intercambiar para una implementación más fácil. ¿Simplemente está buscando el hash _most_ secure que se puede implementar en 50 líneas de Scheme? Incluso si ese algoritmo es probable que se rompa dentro de, digamos, 10 años? –

Respuesta

2

Si prefiere la simplicidad y valor pedagógico sobre la eficiencia entonces la función de hash VSH podría ser una opción. Viene con fuertes argumentos de que VSH es una función hash resistente a colisiones, aunque esta función carece de otras propiedades (por ejemplo, pseudoaleabilidad) que tienen otras funciones hash.

+0

Esto parece ser lo que he estado buscando. Le di un vistazo al documento y acepté tu respuesta. Gracias. – z5h

1

Echa un vistazo a TrueCrypt source. Implementan varias funciones hash fuertes. Solo la advertencia estándar, no es prudente modificar una implementación existente o, peor aún, usar la suya propia. Es casi seguro que inyectará debilidad. Me doy cuenta de que no estás haciendo eso aquí, sino solo un descargo de responsabilidad. :)

4

Si desea una función hash segura para asegurar algo (por ejemplo, como parte de un algoritmo de cifrado), lo mejor sería utilizar una implementación de biblioteca de SHA-512 (o quizás RIPEMD-160 o algunos otros).

Si lo quiere para contraseñas hash, yo diría que una función hash como MASH encajaría en la factura de ser resistente a la fuerza bruta (cuando se usa con una sal) y tablas de arcoiris. Todavía no lo usaría a menos que tuviera requisitos estrictos que prohibieran o me impidieran utilizar una implementación de la biblioteca, pero parece que usted solo tiene esos.

Si lo quiere para algo menos seguro, digamos comprobación de integridad de archivos, casi cualquier cosa funcionaría a menos que esté explícitamente preocupado por usuarios malintencionados que generen colisiones. En ese caso, dependiendo del valor de lo que está protegiendo, podría ir desde algo simple como MASH a algo más resistente como SHA-512 o RIPEMD-320.

2

Para sus requisitos, verificaría el SHA-3 finalists.

Si tiene implementada la primitiva AES para el cifrado, puede reutilizarla para implementar varias de las funciones de manera relativamente simple.

De lo contrario, creo que iría con Cubehash de Daniel Bernstein. Ese parece tener algo de esa "elegancia simple" que estabas buscando.

+0

Gracias. Esto parece una posibilidad interesante. – z5h

2

De acuerdo con la sección 18.12 de la "Criptografía Aplicada" de Bruce Schneier: "Es posible usar un algoritmo de encriptación de clave pública en un modo de encadenamiento de bloque como una función hash unidireccional".

RSA (con la clave privada que se descarta) se enumera a modo de ejemplo. La seguridad es tan fuerte como RSA.

El paso de encriptación RSA es bastante simple de implementar. Especialmente en un lenguaje que tiene enteros de tamaño arbitrario.

Las 2 advertencias son: 1. Mucho más lento que la mayoría de (todas) otras funciones hash seguras. Lo cual está bien para mí. 2. Si ha codificado sus claves públicas en el código, el mundo debería confiar en que descartó sus datos de clave privada. O crea sus propias claves privadas públicas.

Voy a publicar el código tan pronto como tenga un ejemplo de trabajo.

EDITAR: Aquí está. 30 líneas Sencillo. Seguro. EDIT 2: Lo que en realidad incluí es una variante, y puede que no funcione. Vea los comentarios debajo de esta publicación y mire las actualizaciones.

; compute a^d mod n 
(define powmod 
    (lambda (a d n) 
    (cond 
     ((= 0 d) 1) 
     ((= 1 d) (modulo a n)) 
     ((= 0 (modulo d 2)) (modulo (expt (powmod a (/ d 2) n) 2) n)) 
     (else 
     (modulo (* (powmod a 1 n) (powmod a (- d 1) n)) n))))) 

(define foldr 
    (lambda (func end lst) 
    (if (null? lst) 
     end 
     (func (car lst) (foldr func end (cdr lst)))))) 

; something to turn a string into a number 
(define any-string->number 
    (lambda (s) 
    (foldr 
     (lambda (a b) (+ a (* 256 b))) 
     0 
     (map char->integer (string->list s))))) 

; some big primes 
(define p 325981479175658910158495167696993467513669112200235950741366213684181287869366665231) 
(define q 930416184994449450269535709442344346507738432154879695027334802205487824589832585453) 

; hash turns a string into a number 
; see discrete logarithms. the inverse of this is *hard* to compute 
; http://en.wikipedia.org/wiki/Discrete_logarithm 
(define hash 
    (lambda (s) 
    (powmod (any-string->number s) p q))) 
+2

Realmente consideré sugerir eso, pero decidí no hacerlo. Otra desventaja es que la salida es bastante grande: 128 bytes si usa un módulo de 1024 bits. Además: recuerde que debe dividir la entrada en bloques y encadenar los resultados (o simplemente fallar si la entrada es mayor que el módulo). –

+6

Además: lo que ha implementado no es ni RSA ni Diffie-Hellman. En realidad, esto es bastante trivialmente frágil. Encontrar un determinado (a^p mod q), pyq es fácil. El problema del logaritmo discreto es encontrar un dado (p^a mod q), p y q. –

+1

Gracias Rasmus. Has sido útil en este hilo. En la misma sección de "Criptografía Aplicada" que explica el uso de RSA, se menciona este método. No tengo el libro conmigo en este momento, pero estoy bastante seguro de eso. Volveré a verificar cuando llegue a casa. Veo que este no es exactamente el problema del logaritmo discreto. Pero en RSA todavía tenemos el mensaje^e mod n, donde n es (p-1) (q-1) para algunos primos p q, y e es relativamente primo a n. Esto siendo trivialmente frágil haría parecer que RSA también lo es. ¿Puede señalarme en la dirección del algoritmo que rompe esto? – z5h