Criptográficas de los números aleatorios
Explicación con Dephi fuente explicando cómo generar números aleatorios con la debida fuentes de la entropía y de las funciones de hash.
[Criptográficas de los Números Aleatorios]
//Código Fuente de Abajo
Simplemente llamando a Aleatorizar y el uso de la Random() el procedimiento es una grave falla de seguridad en la aplicación buscando a pretect de datos con números aleatorios. Un generador de número aleatorio se presenta es 'aleatoriedad' de la entropía. Borlands Random() procedimiento utiliza una semilla de 32 bits como la entropía, y que la semilla se genera por la selección de procedimiento que obtiene su entropía la hora y fecha del sistema, que son muy probabilístico y se puede probar rápidamente.
Para generar números aleatorios que no puede ser diferenciada de puro caos es una tarea MUY difícil en un equipo, sobre todo porque dependen de los estados internos que a menudo son demasiado predecibles. La idea es reunir la entropía desde el menos predecible de los estados del sistema y dillute que la entropía en el interior de un grupo mucho mayor. La piscina me refiero a que es el estado interno del generador de números aleatorios.
¿QUÉ ES:
Hay propiedades importantes que deben ser respetados siempre y cuando la generación de números aleatorios. Más en concreto, los números al azar la intención de
para el cifrado. Las propiedades que están implicadas en este número aleatorio gerenartors diseño está fuertemente basado en Bruce Schneier Milenrama (www.counterpane.com).
La primera propiedad es para asegurarse de que siempre hay anought de la entropía en la piscina antes de imprimir números aleatorios, de modo que la piscina nunca se entra en un estado debilitado, donde el próximo aleatoria de números de salida se han predictible información.
La siguiente propiedad es muy útil si usted va a utilizar el generador de claves de sesión que va a cambiar varias veces durante una sesión de chat. Es importante que se vea comprometida la clave de no revelar ninguna de las claves anteriores, ni ninguna de las siguiente teclas que se utiliza. Para ello necesitamos eliminar la relación matemática entre los números aleatorios que son de salida y el estado de la piscina.
La tercera propiedad deseada implica que enven si la entropía se reunieron a partir de sus fuentes es de baja calidad (bastante fiable) de la piscina no debe sufrir por la baja entropía y la salida de números aleatorios no debe mostrar ninguna evidencia de esto.
he probado esta unidad ampliamente. El último y el más crucial de la prueba, centrado alrededor de la tercera propiedad. Para tomar un caso extremo, empecé la piscina con nada pero ceros y genera '12 MB (100.000.000 de bits). He utilizado el Acérrimos de la batería de pruebas (http://stat.fsu.edu/'geo/diehard.html) y fue aprobado por todos los 15 con el vuelo de colores... sin recoger ninguna entropía. Con esto me estoy satisfecho de que el generador de números aleatorios de rendimiento y enviar a usted para su uso como una alternativa segura a lo que se ve comúnmente en los programas.
CÓMO FUNCIONA:
-dos entropía recolectores se crean:
[1] un hilo que sigue el movimiento del ratón a intervalos aleatorios de tomar 4bits de la entropía a partir de la posición del ratón y el estado del sistema del temporizador de alta resolución.
[2] una latencia calculadora que obtiene 4bits de la entropía del temporizador de alta resolución cuando se le llama por el principal de la aplicación (esta es utilizada por alling
TKeyGenerator.AddLatency en el evento OnKeyDown de un cuadro de edición, para contar disco duro de latencia, o irq latencia)
Cuando cualquiera de la entropía recolectores ha acumulado 32bits, lo envía a la piscina de entropía.
-La entroyp de la piscina se lleva en la entropía de 32bits en un momento y se utiliza para rellenar una entropía de búfer de 256bits, cuando el buffer está lleno, una de las principales reinicialización se ejecuta.
-El principal reinicialización de las actualizaciones de la primaria a la piscina (un Hash Contexto: el estado interno de una función hash) con la entropía y XORs con la piscina de la semilla (esta semilla se utiliza de la misma forma que el modo aleatorio genera randseed). Después de cada primaria reseed, la semilla (ahora con 256bits de la entropía) está listo para ser utilizado para la salida de números aleatorios si la aplicación llamada así lo desea, pero va a continuar para sembrar de nuevo y recoger la entropía independientemente independientemente de que. Después de las 8 de la primaria reseeds han tenido lugar, un secundario de reinicialización se ejecuta.
-La secundaria reinicialización de las actualizaciones de la secundaria, de la piscina con los contenidos de la primaria a la piscina y luego se vacía el contenido de la primaria a la piscina en un estado sin la entropía. El grupo secundario es persistente en el que nunca se vacían y se llevan la entropía trozos de varios reseeds. Un completamente nuevo de la semilla se genera a partir de la secundaria reinicialización (donde como la forma primaria se modifica con la entropía). Este secundaria reinicialización impide el retroceso de las propiedades (gessing estados anteriores de la piscina) y asegura que no hay es la entropía en la piscina, incluso bajo condiciones donde los nuevos entropía es de baja calidad.
-Cuando la llamada a las necesidades de la aplicación para generar una clave se llama SafeGetKey que se asegura de que no más de 8 conjuntos de 256bits de números aleatorios puede ser generado a partir de una sola reinicialización. Para ello una clave de reserva contador se incrementa cada primaria reseed, y no puede exceder de 8. Cuando se genera un conjunto de números aleatorios la clave de reserva disminuye y la función devolverá fasle si la clave de la reserva está a 0. NOTA: una aplicación puede ignorar la clave de la reserva y la llamada ForceGetKey. Esto es muy arriesgado práctica y yo en serio disuadir del uso de esta función.
-El azar de salida creado por GetKey es una generados con la entropía de la semilla. La semilla se utiliza como una clave de cifrado y, a continuación, permutada (con una expansión-compresión). La nueva semilla se utiliza como datos cifrados. La información es cifrada con la anterior de la semilla y que se ha ampliado el comprimido en 64 rondas. Estas rondas de asegurarse de que es imposible determinar el estado de la semilla, el conjunto principal, la secundaria, de la piscina o de la entorpy búfer a su vez, evita que cualquier persona pueda encontrar la siguiente o anterior salidas.
NOTAS:
-Asignar a una variable de tipo TKeyGenerator y llamarlo .Crear. Esto iniciará el proceso. Cuando haya terminado, llamada .Destropy.
-puede utilizar .KeyCount para averiguar el estado de la tecla de reserva (cómo muchos GetKey llamadas se pueden hacer antes de la próxima reinicialización). Creo firmemente que aprueban aumentar el valor de los MAX_KEY_RESERVE.
-puede manipular la velocidad a la que la entropía se reunieron desde el ratón por la configuración de la MOUSE_INTERVAL constante (en mili-segundos). Un valor inferior a 10 es unrecommended.
-No la comprobación de errores se realiza para asegurarse de que hay una alta frecuencia de un contador en el sistema, este debe ser verificado por la aplicación de llamada. Si no hay contador, el generador de números aleatorios funciona, pero de salida no-aleatorio de números.
-La aplicación debe contar con 32 BYTES de espacio de memoria en una variable para pasar a la GetKey funciones. Ningún error de comprobación que se hace aquí.
-Usted puede cambiar KEY_BUILD_ROUNDS para cualquier valor mayor o igual a 32, pero mayor que 64 es bastante inútil.
/*********************************************************************
/*********************************************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp - NOTA IMPORTANTE -
La fuente de abajo es parte de una biblioteca en el progreso cummulating 3 años de mi investigación. Si usted desea utilizarlo en un programa, un poco de crédito sería bueno.
NSCrypt.pas contiene un pseudo generador de números aleatorios que proviene de una fuente desconocida, y estas implementaciones de Haval y Rijndael [grave] modificaciones de David Barton haval.pas y rijndael.pas se encuentra en la DCPcrypt 1.3 componente de la suite.
Descargar NSCrypt.txt y cambiarle el nombre NSCrypt.pas (tonto webhost) he incluido las funciones de cifrado sepperatly debido a que el total de 1300 líneas juntas.
http://www.eccentrix.com/computer/drmungkee/NSCrypt.txt
(el sitio web real es www.drmungkee.com)
/*********************************************************************
/*********************************************************************
//que vas a tener que lidiar con la documentación anteriormente.
unidad de NoiseSpunge
interfaz
utiliza Windows,Clases,Controles,NSCrypt
const
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SEED_SIZE=8
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PRIMARY_RESEED=SEED_SIZE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SECONDARY_RESEED=SEED_SIZE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //parámetros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MAX_KEY_RESERVE=8
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp KEY_BUILD_ROUNDS=64
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MOUSE_INTERVAL=10
tipo
& nbsp & nbsp & nbsp Key256 = array[0..SEED_SIZE-1] de larga
& nbsp & nbsp & nbsp TNoiseSpungeAddEntropy = procedimiento(Bloque:longword) del objeto
& nbsp & nbsp & nbsp TNoiseSpungeProcedure = procedimiento de objeto
& nbsp & nbsp & nbsp TMouseCollector = class(clase TThread)
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp x,y:integer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Intervalo,Frecuencia,ThisTime,LastTime:TLargeInteger
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendMouseEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp pública
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento SyncSendMouseEntropy
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ejecución del procedimiento de invalidación
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TLatencyCollector = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tiempo:TLargeInteger
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendLatencyEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp pública
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento MeasureLatency
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TEntropyPool = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp de la Semilla:Key256
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyBuffer:Key256
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrimaryPool:Haval_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SecondaryPool:Haval_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrimaryReseedCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp KeyReserve:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento PermuteSeed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento PrimaryReseed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento SecondaryReseed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento AddEntropy(Bloque:longword)
& nbsp & nbsp & nbsp pública
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TKeyGenerator = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyPool:TEntropyPool
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MouseCollector:TMouseCollector
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp LatencyCollector:TLatencyCollector
& nbsp & nbsp & nbsp pública
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp AddLatency:TNoiseSpungeProcedure
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp función KeyCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp función SafeGetKey(var Key):boolean
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento ForcedGetKey var(Llave)
& nbsp & nbsp & nbsp final
aplicación
constructor TMouseCollector.Crear
begin
& nbsp & nbsp & nbsp heredado Crear(true)
& nbsp & nbsp & nbsp Randomize
& nbsp & nbsp & nbsp PrngInit(@PCtx,RandSeed)
& nbsp & nbsp & nbsp FreeOnTerminate:=true
& nbsp & nbsp & nbsp Prioridad:=tpNormal
& nbsp & nbsp & nbsp Reanudar
fin
procedimiento TMouseCollector.SyncSendMouseEntropy
begin
& nbsp & nbsp & nbsp SendMouseEntropy(Bloque)
fin
procedimiento TMouseCollector.ejecutar
var NilHandle:puntero
& nbsp & nbsp & nbsp & nbsp Ociosa:boolean
begin
& nbsp & nbsp & nbsp NilHandle:=nil
& nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp QueryPerformanceFrequency(Frecuencia)
& nbsp & nbsp & nbsp repetir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si Ociosa=false then
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MsgWaitForMultipleObjects(0,NilHandle,falso,MOUSE_INTERVAL,0)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=true
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(ThisTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si ThisTime-LastTime>Intervalo luego
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp if (x<>ratón.cursorpos.x)y(y<>ratón.cursorpos.y) a continuación,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp x:=mouse.cursorpos.x
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp y:=mouse.cursorpos.y
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(Bloque,(((x y 15)xor(y 15))xor(ThisTime y 15))shl
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@PCtx,Bloque)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Sincronizar(SyncSendMouseEntropy)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp - nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Intervalo:=(((( Prng(@PCtx) mod MOUSE_INTERVAL) div 2) MOUSE_INTERVAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *Frecuencia)div 1000
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(LastTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp end else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(LastTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp hasta que sea Terminado=true
fin
constructor TLatencyCollector.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp BitsGathered:=0
fin
procedimiento TLatencyCollector.MeasureLatency
begin
& nbsp & nbsp & nbsp QueryPerformanceCounter(Tiempo)
& nbsp & nbsp & nbsp Inc(Bloque,(Hora y 15)shl BitsGathered)
& nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendLatencyEntropy(Bloque)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp final
fin
constructor TEntropyPool.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp HavalInit(@SecondaryPool)
& nbsp & nbsp & nbsp FillChar(Semilla,SizeOf(Semilla),0)
& nbsp & nbsp & nbsp EntropyCount:=0
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
& nbsp & nbsp & nbsp KeyReserve:=0
fin
procedimiento TEntropyPool.PermuteSeed
var TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i:byte
begin
& nbsp & nbsp & nbsp for i:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@PCtx,Semillas[i])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp HavalOutput(@HCtx,Semillas)
fin
procedimiento TEntropyPool.PrimaryReseed
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp i:byte
begin
& nbsp & nbsp & nbsp HavalUpdate(@PrimaryPool,EntropyBuffer,SizeOf(EntropyBuffer))
& nbsp & nbsp & nbsp si PrimaryReseedCount
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,TempSeed)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp for i:=0 a SEED_SIZE-1 do Semilla[i]:=Semilla[i] xor TempSeed[i]
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(PrimaryReseedCount)
& nbsp & nbsp & nbsp final más SecondaryReseed
& nbsp & nbsp & nbsp FillChar(EntropyBuffer,SizeOf(EntropyBuffer),0)
& nbsp & nbsp & nbsp si KeyReserve
& nbsp & nbsp & nbsp EntropyCount:=0
fin
procedimiento TEntropyPool.SecondaryReseed
begin
& nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,Semillas)
& nbsp & nbsp & nbsp HavalUpdate(@SecondaryPool,Semillas,SizeOf(Semilla))
& nbsp & nbsp & nbsp HavalOutput(@SecondaryPool,Semillas)
& nbsp & nbsp & nbsp PermuteSeed
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
fin
procedimiento TEntropyPool.AddEntropy(Bloque:longword)
begin
& nbsp & nbsp & nbsp Mover(Bloque,puntero(palabra larga(@EntropyBuffer) (EntropyCount*SizeOf(Bloque)))^,SizeOf(Bloque))
& nbsp & nbsp & nbsp Inc(EntropyCount,1)
& nbsp & nbsp & nbsp si EntropyCount=PRIMARY_RESEED luego PrimaryReseed
fin
constructor TKeyGenerator.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp EntropyPool:=TEntropyPool.Crear
& nbsp & nbsp & nbsp MouseCollector:=TMouseCollector.Crear
& nbsp & nbsp & nbsp MouseCollector.SendMouseEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp LatencyCollector:=TLatencyCollector.Crear
& nbsp & nbsp & nbsp LatencyCollector.SendLatencyEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp AddLatency:=LatencyCollector.MeasureLatency
fin
destructor TKeyGenerator.Destruir
begin
& nbsp & nbsp & nbsp MouseCollector.terminar
& nbsp & nbsp & nbsp LatencyCollector.destruir
& nbsp & nbsp & nbsp EntropyPool.destruir
& nbsp & nbsp & nbsp heredado Destruir
fin
función TKeyGenerator.KeyCount:byte
begin
& nbsp & nbsp & nbsp Resultado:=EntropyPool.KeyReserve
fin
función TKeyGenerator.SafeGetKey(var Key):boolean
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp RCtx:Rijndael_CTX
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve=0, entonces
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Salida
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado:=false
& nbsp & nbsp & nbsp end else Result:=true
& nbsp & nbsp & nbsp Mover(EntropyPool.La semilla,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Las semillas)
& nbsp & nbsp & nbsp for i:=0 a KEY_BUILD_ROUNDS-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp para j:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@pctx,TempSeed[j])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp Mover(TempSeed,Clave,SizeOf(TempSeed))
& nbsp & nbsp & nbsp Dic(EntropyPool.KeyReserve,1)
fin
procedimiento TKeyGenerator.ForcedGetKey var(Llave)
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp Mover(EntropyPool.La semilla,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Las semillas)
& nbsp & nbsp & nbsp for i:=0 a KEY_BUILD_ROUNDS-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp para j:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@pctx,TempSeed[j])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp Mover(TempSeed,Clave,SizeOf(TempSeed))
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve<0 entonces Dec(EntropyPool.KeyReserve,1)
fin
final.
(C)Copyright DrMungkee, 2001 (www.drmungkee.com, [email protected])
Criptograficas de los numeros aleatorios
Criptograficas de los numeros aleatorios : Multi-millones de consejos para hacer su vida mas facil.
Explicacion con Dephi fuente explicando como generar numeros aleatorios con la debida fuentes de la entropia y de las funciones de hash.
[Criptograficas de los Numeros Aleatorios]
//Codigo Fuente de Abajo
Simplemente llamando a Aleatorizar y el uso de la Random() el procedimiento es una grave falla de seguridad en la aplicacion buscando a pretect de datos con numeros aleatorios. Un generador de numero aleatorio se presenta es 'aleatoriedad' de la entropia. Borlands Random() procedimiento utiliza una semilla de 32 bits como la entropia, y que la semilla se genera por la seleccion de procedimiento que obtiene su entropia la hora y fecha del sistema, que son muy probabilistico y se puede probar rapidamente.
Para generar numeros aleatorios que no puede ser diferenciada de puro caos es una tarea MUY dificil en un equipo, sobre todo porque dependen de los estados internos que a menudo son demasiado predecibles. La idea es reunir la entropia desde el menos predecible de los estados del sistema y dillute que la entropia en el interior de un grupo mucho mayor. La piscina me refiero a que es el estado interno del generador de numeros aleatorios.
¿QUE ES:
Hay propiedades importantes que deben ser respetados siempre y cuando la generacion de numeros aleatorios. Mas en concreto, los numeros al azar la intencion de
para el cifrado. Las propiedades que estan implicadas en este numero aleatorio gerenartors diseño esta fuertemente basado en Bruce Schneier Milenrama (www.counterpane.com).
La primera propiedad es para asegurarse de que siempre hay anought de la entropia en la piscina antes de imprimir numeros aleatorios, de modo que la piscina nunca se entra en un estado debilitado, donde el proximo aleatoria de numeros de salida se han predictible informacion.
La siguiente propiedad es muy util si usted va a utilizar el generador de claves de sesion que va a cambiar varias veces durante una sesion de chat. Es importante que se vea comprometida la clave de no revelar ninguna de las claves anteriores, ni ninguna de las siguiente teclas que se utiliza. Para ello necesitamos eliminar la relacion matematica entre los numeros aleatorios que son de salida y el estado de la piscina.
La tercera propiedad deseada implica que enven si la entropia se reunieron a partir de sus fuentes es de baja calidad (bastante fiable) de la piscina no debe sufrir por la baja entropia y la salida de numeros aleatorios no debe mostrar ninguna evidencia de esto.
he probado esta unidad ampliamente. El ultimo y el mas crucial de la prueba, centrado alrededor de la tercera propiedad. Para tomar un caso extremo, empece la piscina con nada pero ceros y genera '12 MB (100.000.000 de bits). He utilizado el Acerrimos de la bateria de pruebas (http://stat.fsu.edu/'geo/diehard.html) y fue aprobado por todos los 15 con el vuelo de colores... sin recoger ninguna entropia. Con esto me estoy satisfecho de que el generador de numeros aleatorios de rendimiento y enviar a usted para su uso como una alternativa segura a lo que se ve comunmente en los programas.
COMO FUNCIONA:
-dos entropia recolectores se crean:
[1] un hilo que sigue el movimiento del raton a intervalos aleatorios de tomar 4bits de la entropia a partir de la posicion del raton y el estado del sistema del temporizador de alta resolucion.
[2] una latencia calculadora que obtiene 4bits de la entropia del temporizador de alta resolucion cuando se le llama por el principal de la aplicacion (esta es utilizada por alling
TKeyGenerator.AddLatency en el evento OnKeyDown de un cuadro de edicion, para contar disco duro de latencia, o irq latencia)
Cuando cualquiera de la entropia recolectores ha acumulado 32bits, lo envia a la piscina de entropia.
-La entroyp de la piscina se lleva en la entropia de 32bits en un momento y se utiliza para rellenar una entropia de bufer de 256bits, cuando el buffer esta lleno, una de las principales reinicializacion se ejecuta.
-El principal reinicializacion de las actualizaciones de la primaria a la piscina (un Hash Contexto: el estado interno de una funcion hash) con la entropia y XORs con la piscina de la semilla (esta semilla se utiliza de la misma forma que el modo aleatorio genera randseed). Despues de cada primaria reseed, la semilla (ahora con 256bits de la entropia) esta listo para ser utilizado para la salida de numeros aleatorios si la aplicacion llamada asi lo desea, pero va a continuar para sembrar de nuevo y recoger la entropia independientemente independientemente de que. Despues de las 8 de la primaria reseeds han tenido lugar, un secundario de reinicializacion se ejecuta.
-La secundaria reinicializacion de las actualizaciones de la secundaria, de la piscina con los contenidos de la primaria a la piscina y luego se vacia el contenido de la primaria a la piscina en un estado sin la entropia. El grupo secundario es persistente en el que nunca se vacian y se llevan la entropia trozos de varios reseeds. Un completamente nuevo de la semilla se genera a partir de la secundaria reinicializacion (donde como la forma primaria se modifica con la entropia). Este secundaria reinicializacion impide el retroceso de las propiedades (gessing estados anteriores de la piscina) y asegura que no hay es la entropia en la piscina, incluso bajo condiciones donde los nuevos entropia es de baja calidad.
-Cuando la llamada a las necesidades de la aplicacion para generar una clave se llama SafeGetKey que se asegura de que no mas de 8 conjuntos de 256bits de numeros aleatorios puede ser generado a partir de una sola reinicializacion. Para ello una clave de reserva contador se incrementa cada primaria reseed, y no puede exceder de 8. Cuando se genera un conjunto de numeros aleatorios la clave de reserva disminuye y la funcion devolvera fasle si la clave de la reserva esta a 0. NOTA: una aplicacion puede ignorar la clave de la reserva y la llamada ForceGetKey. Esto es muy arriesgado practica y yo en serio disuadir del uso de esta funcion.
-El azar de salida creado por GetKey es una generados con la entropia de la semilla. La semilla se utiliza como una clave de cifrado y, a continuacion, permutada (con una expansion-compresion). La nueva semilla se utiliza como datos cifrados. La informacion es cifrada con la anterior de la semilla y que se ha ampliado el comprimido en 64 rondas. Estas rondas de asegurarse de que es imposible determinar el estado de la semilla, el conjunto principal, la secundaria, de la piscina o de la entorpy bufer a su vez, evita que cualquier persona pueda encontrar la siguiente o anterior salidas.
NOTAS:
-Asignar a una variable de tipo TKeyGenerator y llamarlo .Crear. Esto iniciara el proceso. Cuando haya terminado, llamada .Destropy.
-puede utilizar .KeyCount para averiguar el estado de la tecla de reserva (como muchos GetKey llamadas se pueden hacer antes de la proxima reinicializacion). Creo firmemente que aprueban aumentar el valor de los MAX_KEY_RESERVE.
-puede manipular la velocidad a la que la entropia se reunieron desde el raton por la configuracion de la MOUSE_INTERVAL constante (en mili-segundos). Un valor inferior a 10 es unrecommended.
-No la comprobacion de errores se realiza para asegurarse de que hay una alta frecuencia de un contador en el sistema, este debe ser verificado por la aplicacion de llamada. Si no hay contador, el generador de numeros aleatorios funciona, pero de salida no-aleatorio de numeros.
-La aplicacion debe contar con 32 BYTES de espacio de memoria en una variable para pasar a la GetKey funciones. Ningun error de comprobacion que se hace aqui.
-Usted puede cambiar KEY_BUILD_ROUNDS para cualquier valor mayor o igual a 32, pero mayor que 64 es bastante inutil.
/*********************************************************************
/*********************************************************************
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp - NOTA IMPORTANTE -
La fuente de abajo es parte de una biblioteca en el progreso cummulating 3 años de mi investigacion. Si usted desea utilizarlo en un programa, un poco de credito seria bueno.
NSCrypt.pas contiene un pseudo generador de numeros aleatorios que proviene de una fuente desconocida, y estas implementaciones de Haval y Rijndael [grave] modificaciones de David Barton haval.pas y rijndael.pas se encuentra en la DCPcrypt 1.3 componente de la suite.
Descargar NSCrypt.txt y cambiarle el nombre NSCrypt.pas (tonto webhost) he incluido las funciones de cifrado sepperatly debido a que el total de 1300 lineas juntas.
http://www.eccentrix.com/computer/drmungkee/NSCrypt.txt
(el sitio web real es www.drmungkee.com)
/*********************************************************************
/*********************************************************************
//que vas a tener que lidiar con la documentacion anteriormente.
unidad de NoiseSpunge
interfaz
utiliza Windows,Clases,Controles,NSCrypt
const
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SEED_SIZE=8
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PRIMARY_RESEED=SEED_SIZE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SECONDARY_RESEED=SEED_SIZE
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp //parametros
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MAX_KEY_RESERVE=8
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp KEY_BUILD_ROUNDS=64
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MOUSE_INTERVAL=10
tipo
& nbsp & nbsp & nbsp Key256 = array[0..SEED_SIZE-1] de larga
& nbsp & nbsp & nbsp TNoiseSpungeAddEntropy = procedimiento(Bloque:longword) del objeto
& nbsp & nbsp & nbsp TNoiseSpungeProcedure = procedimiento de objeto
& nbsp & nbsp & nbsp TMouseCollector = class(clase TThread)
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp x,y:integer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Intervalo,Frecuencia,ThisTime,LastTime:TLargeInteger
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendMouseEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp publica
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento SyncSendMouseEntropy
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ejecucion del procedimiento de invalidacion
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TLatencyCollector = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:longword
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Tiempo:TLargeInteger
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendLatencyEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp publica
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento MeasureLatency
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TEntropyPool = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp de la Semilla:Key256
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyBuffer:Key256
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrimaryPool:Haval_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SecondaryPool:Haval_CTX
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrimaryReseedCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp KeyReserve:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento PermuteSeed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento PrimaryReseed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento SecondaryReseed
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento AddEntropy(Bloque:longword)
& nbsp & nbsp & nbsp publica
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp TKeyGenerator = clase
& nbsp & nbsp & nbsp protegido
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp EntropyPool:TEntropyPool
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MouseCollector:TMouseCollector
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp LatencyCollector:TLatencyCollector
& nbsp & nbsp & nbsp publica
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp AddLatency:TNoiseSpungeProcedure
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp constructor Create
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp funcion KeyCount:byte
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp funcion SafeGetKey(var Key):boolean
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp procedimiento ForcedGetKey var(Llave)
& nbsp & nbsp & nbsp final
aplicacion
constructor TMouseCollector.Crear
begin
& nbsp & nbsp & nbsp heredado Crear(true)
& nbsp & nbsp & nbsp Randomize
& nbsp & nbsp & nbsp PrngInit(@PCtx,RandSeed)
& nbsp & nbsp & nbsp FreeOnTerminate:=true
& nbsp & nbsp & nbsp Prioridad:=tpNormal
& nbsp & nbsp & nbsp Reanudar
fin
procedimiento TMouseCollector.SyncSendMouseEntropy
begin
& nbsp & nbsp & nbsp SendMouseEntropy(Bloque)
fin
procedimiento TMouseCollector.ejecutar
var NilHandle:puntero
& nbsp & nbsp & nbsp & nbsp Ociosa:boolean
begin
& nbsp & nbsp & nbsp NilHandle:=nil
& nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp QueryPerformanceFrequency(Frecuencia)
& nbsp & nbsp & nbsp repetir
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si Ociosa=false then
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp MsgWaitForMultipleObjects(0,NilHandle,falso,MOUSE_INTERVAL,0)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=true
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(ThisTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si ThisTime-LastTime>Intervalo luego
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp if (x<>raton.cursorpos.x)y(y<>raton.cursorpos.y) a continuacion,
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp x:=mouse.cursorpos.x
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp y:=mouse.cursorpos.y
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(Bloque,(((x y 15)xor(y 15))xor(ThisTime y 15))shl
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@PCtx,Bloque)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Sincronizar(SyncSendMouseEntropy)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp - nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Intervalo:=(((( Prng(@PCtx) mod MOUSE_INTERVAL) div 2) MOUSE_INTERVAL)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp *Frecuencia)div 1000
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(LastTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp end else
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp QueryPerformanceCounter(LastTime)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Ociosa:=false
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp hasta que sea Terminado=true
fin
constructor TLatencyCollector.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp BitsGathered:=0
fin
procedimiento TLatencyCollector.MeasureLatency
begin
& nbsp & nbsp & nbsp QueryPerformanceCounter(Tiempo)
& nbsp & nbsp & nbsp Inc(Bloque,(Hora y 15)shl BitsGathered)
& nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp SendLatencyEntropy(Bloque)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Bloque:=0
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp final
fin
constructor TEntropyPool.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp HavalInit(@SecondaryPool)
& nbsp & nbsp & nbsp FillChar(Semilla,SizeOf(Semilla),0)
& nbsp & nbsp & nbsp EntropyCount:=0
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
& nbsp & nbsp & nbsp KeyReserve:=0
fin
procedimiento TEntropyPool.PermuteSeed
var TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i:byte
begin
& nbsp & nbsp & nbsp for i:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@PCtx,Semillas[i])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp HavalOutput(@HCtx,Semillas)
fin
procedimiento TEntropyPool.PrimaryReseed
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp i:byte
begin
& nbsp & nbsp & nbsp HavalUpdate(@PrimaryPool,EntropyBuffer,SizeOf(EntropyBuffer))
& nbsp & nbsp & nbsp si PrimaryReseedCount
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,TempSeed)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp for i:=0 a SEED_SIZE-1 do Semilla[i]:=Semilla[i] xor TempSeed[i]
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Inc(PrimaryReseedCount)
& nbsp & nbsp & nbsp final mas SecondaryReseed
& nbsp & nbsp & nbsp FillChar(EntropyBuffer,SizeOf(EntropyBuffer),0)
& nbsp & nbsp & nbsp si KeyReserve
& nbsp & nbsp & nbsp EntropyCount:=0
fin
procedimiento TEntropyPool.SecondaryReseed
begin
& nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,Semillas)
& nbsp & nbsp & nbsp HavalUpdate(@SecondaryPool,Semillas,SizeOf(Semilla))
& nbsp & nbsp & nbsp HavalOutput(@SecondaryPool,Semillas)
& nbsp & nbsp & nbsp PermuteSeed
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
fin
procedimiento TEntropyPool.AddEntropy(Bloque:longword)
begin
& nbsp & nbsp & nbsp Mover(Bloque,puntero(palabra larga(@EntropyBuffer) (EntropyCount*SizeOf(Bloque)))^,SizeOf(Bloque))
& nbsp & nbsp & nbsp Inc(EntropyCount,1)
& nbsp & nbsp & nbsp si EntropyCount=PRIMARY_RESEED luego PrimaryReseed
fin
constructor TKeyGenerator.Crear
begin
& nbsp & nbsp & nbsp heredado Crear
& nbsp & nbsp & nbsp EntropyPool:=TEntropyPool.Crear
& nbsp & nbsp & nbsp MouseCollector:=TMouseCollector.Crear
& nbsp & nbsp & nbsp MouseCollector.SendMouseEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp LatencyCollector:=TLatencyCollector.Crear
& nbsp & nbsp & nbsp LatencyCollector.SendLatencyEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp AddLatency:=LatencyCollector.MeasureLatency
fin
destructor TKeyGenerator.Destruir
begin
& nbsp & nbsp & nbsp MouseCollector.terminar
& nbsp & nbsp & nbsp LatencyCollector.destruir
& nbsp & nbsp & nbsp EntropyPool.destruir
& nbsp & nbsp & nbsp heredado Destruir
fin
funcion TKeyGenerator.KeyCount:byte
begin
& nbsp & nbsp & nbsp Resultado:=EntropyPool.KeyReserve
fin
funcion TKeyGenerator.SafeGetKey(var Key):boolean
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp RCtx:Rijndael_CTX
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve=0, entonces
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Salida
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp Resultado:=false
& nbsp & nbsp & nbsp end else Result:=true
& nbsp & nbsp & nbsp Mover(EntropyPool.La semilla,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Las semillas)
& nbsp & nbsp & nbsp for i:=0 a KEY_BUILD_ROUNDS-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp para j:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@pctx,TempSeed[j])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp Mover(TempSeed,Clave,SizeOf(TempSeed))
& nbsp & nbsp & nbsp Dic(EntropyPool.KeyReserve,1)
fin
procedimiento TKeyGenerator.ForcedGetKey var(Llave)
var TempSeed:Key256
& nbsp & nbsp & nbsp & nbsp TempBuffer:array[0..1]de Key256
& nbsp & nbsp & nbsp & nbsp PCtx:Prng_CTX
& nbsp & nbsp & nbsp & nbsp HCtx:Haval_CTX
& nbsp & nbsp & nbsp & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp Mover(EntropyPool.La semilla,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Las semillas)
& nbsp & nbsp & nbsp for i:=0 a KEY_BUILD_ROUNDS-1 hacer
& nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp para j:=0 a SEED_SIZE-1 hacer
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp empezar
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp PrngInit(@pctx,TempSeed[j])
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp final
& nbsp & nbsp & nbsp Mover(TempSeed,Clave,SizeOf(TempSeed))
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve<0 entonces Dec(EntropyPool.KeyReserve,1)
fin
final.
(C)Copyright DrMungkee, 2001 (www.drmungkee.com, [email protected])
Criptográficas de los números aleatorios
By Consejos Y Trucos
Criptográficas de los números aleatorios : Multi-millones de consejos para hacer su vida más fácil.