Chiffrement des nombres aléatoires
Explication avec Dephi source expliquant comment générer des nombres aléatoires avec des bonnes sources d'entropie et de fonctions de hachage.
[Cryptographiques Nombres Aléatoires]
//le Code Source Soufflet
Simplement en appelant Aléatoire et en utilisant le Random() procédure est une grave faille de sécurité dans l'application cherchant à pretect de données avec des nombres aléatoires. Un générateur de nombre aléatoire obtient est 'aléatoire' de l'entropie. Borlands Random() est une procédure qui utilise un 32bit semences comme l'entropie, et que la graine est généré par la fonction Randomize procédure qui obtient son entropie du système, l'heure et la date sont très probabiliste et peut être testée rapidement.
Pour générer des nombres aléatoires qui ne peuvent être différenciées à partir de pur chaos est une tâche TRÈS difficile sur un ordinateur, principalement parce que vous comptez sur les états internes qui sont souvent trop prévisible. L'idée est de rassembler l'entropie de la moins prévisible états du système et dillute que l'entropie à l'intérieur d'un beaucoup plus grand bassin. La piscine je me réfère à l'est de l'état interne du générateur de nombre aléatoire.
CE que C'EST:
Il y a des propriétés importantes qui doivent être respectées lors de la génération de nombres aléatoires. Plus spécialement, de nombres aléatoires destinés
pour le chiffrement. Les propriétés impliqués dans ce numéro aléatoire gerenartors de conception sont fortement basées sur Bruce Schneier l'Achillée millefeuille (www.counterpane.com).
La première propriété est de s'assurer qu'il est toujours anought entropie dans la piscine avant de outputing nombres aléatoires, de sorte que la piscine ne pénètre jamais dans un état de faiblesse où le côté aléatoire de numéros de sortie ont était prévisible d'informations.
La propriété suivante est très pratique si vous allez être en utilisant le générateur de rendre les clés de session qui va changer plusieurs fois au cours d'une session de chat. Il est important qu'un compromis ne seront pas révéler tout de clés précédentes, ni aucun de la prochaine clés qui seront utilisés. Pour ce faire, nous avons besoin d'éliminer la relation mathématique entre les nombres aléatoires qui sont de sortie et l'état de la piscine.
La troisième souhaité propriété implique que enven si l'entropie recueillies à partir de vos sources est de mauvaise qualité (assez prévisible) de la piscine ne doit pas souffrir de la faible entropie et la sortie de nombres aléatoires ne doit montrer aucune preuve de cela.
j'ai testé cet appareil de manière intensive. La dernière et la plus cruciale du test centré autour de la troisième propriété. Pour prendre un cas extrême, j'ai commencé la piscine avec rien mais des zéros en elle et a généré des '12 MO (100,000,000 bits). J'ai utilisé les Irréductibles de la batterie de tests (http://stat.fsu.edu/'geo/diehard.html) et il a passé tous les 15 avec brio... sans recueillir toute l'entropie. Avec cela, je suis satisfait de la du générateur de nombre aléatoire de la performance et de la soumettre à vous de l'utiliser comme une alternative sûre à ce qui est communément observé dans les programmes.
COMMENT CELA FONCTIONNE:
-deux entropie cueilleurs sont créés:
[1] un thread qui suit le mouvement de la souris à des intervalles aléatoires prenant 4bits de l'entropie à partir de la position de la souris et de l'état du système de haute résolution du timer.
[2] un temps de latence de la calculatrice qui obtient 4bits de l'entropie de l'timer haute résolution, lorsqu'il est appelé par l'application principale (il est utilisé par alling
TKeyGenerator.AddLatency sur l'événement OnKeyDown d'une zone d'édition, à compter de disque dur de latence, ou irq latence)
Lorsque l'une de l'entropie cueilleurs a accumulé 32bits, il l'envoie à l'entropie.
-Le entroyp piscine prend de l'entropie 32bits à un moment et qu'il utilise pour remplir une entropie de la mémoire tampon de 256bits, lorsque la mémoire est pleine, l'un des principaux réamorçage est exécuté.
-Le principal réensemencer les mises à jour de la primaire la piscine (un Hash Contexte: état interne d'une fonction de hachage, avec l'entropie et XORs avec la piscine de semences (cette graine est utilisé de la même façon la façon aléatoire génère randseed). Après chaque reseed, la graine (avec 256bits de l'entropie) est prêt à être utilisé pour générer des nombres aléatoires si l'application appelante désire, mais il continuera à réamorcer et de recueillir de l'entropie quel que soit indépendamment de ce que. Après 8 primaire réinitialisations ont eu lieu, un secondaire de réamorçage est exécuté.
-Le secondaire réensemencer les mises à jour du secondaire de la piscine avec le contenu de la primaire la piscine, puis vide le contenu de la primaire la piscine dans un état sans l'entropie. Le pool secondaire est persistant en ce qu'il n'est jamais vidée et de transporter de l'entropie bits à partir de divers réinitialisations. Un complètement nouveau de semences est généré à partir du secondaire réamorçage (où, comme le primaire sur le modifie avec l'entropie). Cette deuxième réamorçage empêche le retour en arrière des propriétés (gessing états précédents de la piscine) et s'assure qu'il existe d'entropie dans la piscine, même dans des conditions où la nouvelle entropie est de mauvaise qualité.
-Lorsque l'application appelante doit générer une clé, il appelle SafeGetKey qui assure que pas plus de 8 jeux de 256bits de nombres aléatoires peut être généré à partir d'un unique effectuer un réamorçage. Pour ce faire, une clé de réserve compteur est incrémenté à chaque primaire reseed, et ne doit pas dépasser 8. Lorsque vous générez un ensemble de nombres aléatoires, la clé de la réserve est décrémenté et la fonction retournera fasle si la clé de réserve est à 0. REMARQUE: une application peut ignorer la clé de la réserve et de l'appel ForceGetKey. C'est très pratique risquée et je vous déconseille fortement l'utilisation de cette fonction.
-Le hasard de sortie créé par GetKey est généré avec l'entropie de la piscine, de la graine. La graine est utilisée comme une clé de chiffrement, puis permutées (avec une extension-compression). Les nouvelles graines sont utilisées comme des données chiffrées. Il est chiffré avec la précédente semences et élargi compressé en 64 tours. Ces tours s'assurer qu'il est impossible de déterminer l'état de la graine, la primaire la piscine, le pool secondaire ou la entorpy tampon, à son tour, empêchant quiconque de trouver le précédent ou suivant les sorties.
REMARQUES:
-Affecter une variable de type TKeyGenerator et de l'appeler .Créer. Cela va démarrer le processus. Lorsque vous avez terminé, appel .Destropy.
-Vous pouvez utiliser .KeyCount de déterminer l'état de la clé de réserve (combien de GetKey les appels peuvent être effectués avant le prochain réamorçage). Je vous tolère l'augmentation de la valeur de MAX_KEY_RESERVE.
-Vous pouvez manipuler la vitesse à laquelle l'entropie recueillies à partir de la souris par la définition de la MOUSE_INTERVAL constante (en milli-secondes). Une valeur inférieure à 10 est obsolète.
-Pas de contrôle d'erreur est effectué afin de s'assurer d'un haut-compteur de fréquence sur le système, ce doit être vérifiée par l'application appelante. S'il n'existe pas de compteur, le générateur de nombre aléatoires de travail mais il n'y aura non-aléatoire de nombres.
-La demande doit fournir des 32 OCTETS de la mémoire de l'espace dans une variable à transmettre à la GetKey fonctions. Pas de contrôle d'erreur est fait ici.
-Vous pouvez changer KEY_BUILD_ROUNDS à n'importe quelle valeur supérieure ou égale à 32, mais plus de 64 est tout à fait inutile.
/*********************************************************************
/*********************************************************************
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! - REMARQUE IMPORTANTE -
La source soufflet est partie d'une bibliothèque en cours cummulating 3 ans de ma recherche. Si vous voulez l'utiliser dans un programme, un peu de crédit, ce serait bien.
NSCrypt.pas contient un générateur de nombre pseudo-aléatoire qui provient d'une source inconnue, et ces implémentations de Haval et Rijndael sont [grave] modifications de David Barton est haval.pas et de rijndael.pas trouvé dans le DCPcrypt 1.3 composants de la suite.
Télécharger NSCrypt.txt et le renommer NSCrypt.pas (idiot hébergeur), j'ai inclus les fonctions cryptographiques sepperatly parce qu'ils total de 1300 lignes ensemble.
http://www.eccentrix.com/computer/drmungkee/NSCrypt.txt
(le site web réel est www.drmungkee.com)
/*********************************************************************
/*********************************************************************
//vous aurez à traiter avec la documentation ci-dessus.
unité de NoiseSpunge
interface
utilise Windows,les cours,les Contrôles,les NSCrypt
const
& ! & ! & ! & ! & ! & nbsp SEED_SIZE=8
& ! & ! & ! & ! & ! & nbsp PRIMARY_RESEED=SEED_SIZE
& ! & ! & ! & ! & ! & nbsp SECONDARY_RESEED=SEED_SIZE
& ! & ! & ! & ! & ! & nbsp //paramètres
& ! & ! & ! & ! & ! & nbsp MAX_KEY_RESERVE=8
& ! & ! & ! & ! & ! & nbsp KEY_BUILD_ROUNDS=64
& ! & ! & ! & ! & ! & nbsp MOUSE_INTERVAL=10
type
& nbsp & nbsp & nbsp Key256 = array[0..SEED_SIZE-1] de longword
& nbsp & nbsp & nbsp TNoiseSpungeAddEntropy = procédure(Bloc:longword) de l'objet
& nbsp & nbsp & nbsp TNoiseSpungeProcedure = procédure de l'objet
& nbsp & nbsp & nbsp TMouseCollector = (de la classe TThread)
& nbsp & nbsp & nbsp protégé
& ! & ! & ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & ! & ! & nbsp x,y:entier
& ! & ! & ! & ! & ! & nbsp Bloc:longword
& ! & ! & ! & ! & ! & nbsp BitsGathered:longword
& ! & ! & ! & ! & ! & nbsp Intervalle,la Fréquence,la ThisTime,LastTime:TLargeInteger
& ! & ! & ! & ! & ! & nbsp SendMouseEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Créer
& ! & ! & ! & ! & ! & nbsp procédure SyncSendMouseEntropy
& ! & ! & ! & ! & ! & nbsp procédure Exécutez remplacer
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TLatencyCollector = classe
& ! & ! & nbsp protégé
& ! & ! & ! & ! & ! & nbsp Bloc:longword
& ! & ! & ! & ! & ! & nbsp BitsGathered:longword
& ! & ! & ! & ! & ! & nbsp Temps:TLargeInteger
& ! & ! & ! & ! & ! & nbsp SendLatencyEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Créer
& ! & ! & ! & ! & ! & nbsp procédure MeasureLatency
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TEntropyPool = classe
& nbsp & nbsp & nbsp protégé
& ! & ! & ! & ! & ! & nbsp Graine:Key256
& ! & ! & ! & ! & ! & nbsp EntropyBuffer:Key256
& ! & ! & ! & ! & ! & nbsp PrimaryPool:Haval_CTX
& ! & ! & ! & ! & ! & nbsp SecondaryPool:Haval_CTX
& ! & ! & ! & ! & ! & nbsp PrimaryReseedCount:octet
& ! & ! & ! & ! & ! & nbsp EntropyCount:byte
& ! & ! & ! & ! & ! & nbsp KeyReserve:octet
& ! & ! & ! & ! & ! & nbsp procédure PermuteSeed
& ! & ! & ! & ! & ! & nbsp procédure PrimaryReseed
& ! & ! & ! & ! & ! & nbsp procédure SecondaryReseed
& ! & ! & ! & ! & ! & nbsp procédure AddEntropy(Bloc:longword)
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Créer
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TKeyGenerator = classe
& nbsp & nbsp & nbsp protégé
& ! & ! & ! & ! & ! & nbsp EntropyPool:TEntropyPool
& ! & ! & ! & ! & ! & nbsp MouseCollector:TMouseCollector
& ! & ! & ! & ! & ! & nbsp LatencyCollector:TLatencyCollector
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp AddLatency:TNoiseSpungeProcedure
& ! & ! & ! & ! & ! & nbsp constructeur Créer
& ! & ! & ! & ! & ! & nbsp destructeur de Détruire remplacer
& ! & ! & ! & ! & ! & nbsp fonction KeyCount:octet
& ! & ! & ! & ! & ! & nbsp fonction SafeGetKey(var Key):boolean
& ! & ! & ! & ! & ! & nbsp procédure ForcedGetKey(var Key)
& nbsp & nbsp & nbsp fin
application
constructeur TMouseCollector.Créer
begin
& nbsp & nbsp & nbsp hérité de Créer(true)
& nbsp & nbsp & nbsp Aléatoire
& nbsp & nbsp & nbsp PrngInit(@PCtx,RandSeed)
& nbsp & nbsp & nbsp FreeOnTerminate:=true
& nbsp & nbsp & nbsp Priorité:=tpNormal
& nbsp & nbsp & nbsp Cv
fin
procédure TMouseCollector.SyncSendMouseEntropy
begin
& nbsp & nbsp & nbsp SendMouseEntropy(Bloc)
fin
procédure TMouseCollector.exécuter
var NilHandle:pointeur
& ! & ! & ! & nbsp Ralenti:boolean
begin
& nbsp & nbsp & nbsp NilHandle:=nil
& nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp Ralenti:=false
& nbsp & nbsp & nbsp QueryPerformanceFrequency(Fréquence)
& nbsp & nbsp & nbsp repeat
& ! & ! & ! & ! & ! & nbsp si Inactif=false then
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp MsgWaitForMultipleObjects(0,NilHandle,faux,MOUSE_INTERVAL,0)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Ralenti:=true
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(ThisTime)
& ! & ! & ! & ! & ! & nbsp si ThisTime-LastTime>Intervalle puis
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (x<>de la souris.cursorpos.x)et(y<>de la souris.cursorpos.y) puis
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp x:=mouse.cursorpos.x
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp y:=mouse.cursorpos.y
& ! & ! & ! & ! & ! & ! & nbsp & ! & ! & ! & ! & nbsp Inc(Bloc,(((x et 15)xor(y et 15))xor(ThisTime et 15))shl
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp BitsGathered)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Inc(BitsGathered,4)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si BitsGathered=32
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@PCtx,Bloc)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Synchroniser(SyncSendMouseEntropy)
& ! & ! & ! & ! & ! & ! & ! & nbsp - ! & ! & ! & ! & ! & ! & nbsp Bloc:=0
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp BitsGathered:=0
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Intervalle:=(((( Prng(@PCtx) mod MOUSE_INTERVAL) div 2) MOUSE_INTERVAL)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp *Fréquence)div 1000
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(LastTime)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Arrêtés:=false
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin else
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(LastTime)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Ralenti:=false
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& nbsp & nbsp & nbsp jusqu'à sa Résiliation=true
fin
constructeur TLatencyCollector.Créer
begin
& nbsp & nbsp & nbsp hérité de Créer
& nbsp & nbsp & nbsp Bloc:=0
& nbsp & nbsp & nbsp BitsGathered:=0
fin
procédure TLatencyCollector.MeasureLatency
begin
& nbsp & nbsp & nbsp QueryPerformanceCounter(Temps)
& nbsp & nbsp & nbsp Inc(Bloc,(Temps et 15)shl BitsGathered)
& nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp SendLatencyEntropy(Bloc)
& ! & ! & ! & ! & ! & nbsp Bloc:=0
& ! & ! & ! & ! & ! & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp fin
fin
constructeur TEntropyPool.Créer
begin
& nbsp & nbsp & nbsp hérité de Créer
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp HavalInit(@SecondaryPool)
& nbsp & nbsp & nbsp FillChar(Semences,SizeOf(Graine),0)
& nbsp & nbsp & nbsp EntropyCount:=0
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
& nbsp & nbsp & nbsp KeyReserve:=0
fin
procédure TEntropyPool.PermuteSeed
var TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i:byte
begin
& nbsp & nbsp & nbsp for i:=De 0 à SEED_SIZE-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp PrngInit(@PCtx,des Semences[i])
& ! & ! & ! & ! & ! & nbsp TempBuffer[0,i]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp TempBuffer[1,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp HavalOutput(@HCtx,Semences)
fin
procédure TEntropyPool.PrimaryReseed
var TempSeed:Key256
& ! & ! & ! & nbsp i:byte
begin
& nbsp & nbsp & nbsp HavalUpdate(@PrimaryPool,EntropyBuffer,SizeOf(EntropyBuffer))
& nbsp & nbsp & nbsp si PrimaryReseedCount
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp HavalOutput(@PrimaryPool,TempSeed)
& ! & ! & ! & ! & ! & nbsp for i:=0 to SEED_SIZE-1 ne Semences[i]:=Semences[i] xor TempSeed[i]
& ! & ! & ! & ! & ! & nbsp Inc(PrimaryReseedCount)
& nbsp & nbsp & nbsp fin d'autre SecondaryReseed
& nbsp & nbsp & nbsp FillChar(EntropyBuffer,SizeOf(EntropyBuffer),0)
& nbsp & nbsp & nbsp si KeyReserve
& nbsp & nbsp & nbsp EntropyCount:=0
fin
procédure TEntropyPool.SecondaryReseed
begin
& nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,Semences)
& nbsp & nbsp & nbsp HavalUpdate(@SecondaryPool,Semences,SizeOf(Semences))
& nbsp & nbsp & nbsp HavalOutput(@SecondaryPool,Semences)
& nbsp & nbsp & nbsp PermuteSeed
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
fin
procédure TEntropyPool.AddEntropy(Bloc:longword)
begin
& nbsp & nbsp & nbsp Déplacer(Bloc,pointeur(longword(@EntropyBuffer) (EntropyCount*SizeOf(Bloc)))^,SizeOf(Bloc))
& nbsp & nbsp & nbsp Inc(EntropyCount,1)
& nbsp & nbsp & nbsp si EntropyCount=PRIMARY_RESEED puis PrimaryReseed
fin
constructeur TKeyGenerator.Créer
begin
& nbsp & nbsp & nbsp hérité de Créer
& nbsp & nbsp & nbsp EntropyPool:=TEntropyPool.Créer
& nbsp & nbsp & nbsp MouseCollector:=TMouseCollector.Créer
& nbsp & nbsp & nbsp MouseCollector.SendMouseEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp LatencyCollector:=TLatencyCollector.Créer
& nbsp & nbsp & nbsp LatencyCollector.SendLatencyEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp AddLatency:=LatencyCollector.MeasureLatency
fin
destructeur TKeyGenerator.Détruire
begin
& nbsp & nbsp & nbsp MouseCollector.résilier
& nbsp & nbsp & nbsp LatencyCollector.détruire
& nbsp & nbsp & nbsp EntropyPool.détruire
& nbsp & nbsp & nbsp hérité de Détruire
fin
fonction de TKeyGenerator.KeyCount:octet
begin
& nbsp & nbsp & nbsp Résultat:=EntropyPool.KeyReserve
fin
fonction de TKeyGenerator.SafeGetKey(var Key):boolean
var TempSeed:Key256
& ! & ! & ! & nbsp TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp RCtx:Rijndael_CTX
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve=0, alors
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp Sortie
& ! & ! & ! & ! & ! & nbsp Result:=false
& nbsp & nbsp & nbsp fin else Result:=true
& nbsp & nbsp & nbsp Déplacer(EntropyPool.Semences,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Graine)
& nbsp & nbsp & nbsp for i:=0 to KEY_BUILD_ROUNDS-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& ! & ! & ! & ! & ! & nbsp pour j:=0 pour SEED_SIZE-1 do
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@pctx,TempSeed[j])
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp HavalInit(@HCtx)
& ! & ! & ! & ! & ! & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& ! & ! & ! & ! & ! & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp Déplacer(TempSeed,Clé,SizeOf(TempSeed))
& nbsp & nbsp & nbsp Dec(EntropyPool.KeyReserve,1)
fin
procédure TKeyGenerator.ForcedGetKey(var Key)
var TempSeed:Key256
& ! & ! & ! & nbsp TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i,j:octet
begin
& nbsp & nbsp & nbsp Déplacer(EntropyPool.Semences,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Graine)
& nbsp & nbsp & nbsp for i:=0 to KEY_BUILD_ROUNDS-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& ! & ! & ! & ! & ! & nbsp pour j:=0 pour SEED_SIZE-1 do
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@pctx,TempSeed[j])
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp HavalInit(@HCtx)
& ! & ! & ! & ! & ! & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& ! & ! & ! & ! & ! & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp Déplacer(TempSeed,Clé,SizeOf(TempSeed))
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve<0 alors Dec(EntropyPool.KeyReserve,1)
fin
à la fin.
(C)Copyright DrMungkee, 2001 (www.drmungkee.com, [email protected])
Chiffrement des nombres aleatoires
Chiffrement des nombres aleatoires : Plusieurs milliers de conseils pour vous faciliter la vie.
Explication avec Dephi source expliquant comment generer des nombres aleatoires avec des bonnes sources d'entropie et de fonctions de hachage.
[Cryptographiques Nombres Aleatoires]
//le Code Source Soufflet
Simplement en appelant Aleatoire et en utilisant le Random() procedure est une grave faille de securite dans l'application cherchant a pretect de donnees avec des nombres aleatoires. Un generateur de nombre aleatoire obtient est 'aleatoire' de l'entropie. Borlands Random() est une procedure qui utilise un 32bit semences comme l'entropie, et que la graine est genere par la fonction Randomize procedure qui obtient son entropie du systeme, l'heure et la date sont tres probabiliste et peut etre testee rapidement.
Pour generer des nombres aleatoires qui ne peuvent etre differenciees a partir de pur chaos est une tache TRES difficile sur un ordinateur, principalement parce que vous comptez sur les etats internes qui sont souvent trop previsible. L'idee est de rassembler l'entropie de la moins previsible etats du systeme et dillute que l'entropie a l'interieur d'un beaucoup plus grand bassin. La piscine je me refere a l'est de l'etat interne du generateur de nombre aleatoire.
CE que C'EST:
Il y a des proprietes importantes qui doivent etre respectees lors de la generation de nombres aleatoires. Plus specialement, de nombres aleatoires destines
pour le chiffrement. Les proprietes impliques dans ce numero aleatoire gerenartors de conception sont fortement basees sur Bruce Schneier l'Achillee millefeuille (www.counterpane.com).
La premiere propriete est de s'assurer qu'il est toujours anought entropie dans la piscine avant de outputing nombres aleatoires, de sorte que la piscine ne penetre jamais dans un etat de faiblesse ou le cote aleatoire de numeros de sortie ont etait previsible d'informations.
La propriete suivante est tres pratique si vous allez etre en utilisant le generateur de rendre les cles de session qui va changer plusieurs fois au cours d'une session de chat. Il est important qu'un compromis ne seront pas reveler tout de cles precedentes, ni aucun de la prochaine cles qui seront utilises. Pour ce faire, nous avons besoin d'eliminer la relation mathematique entre les nombres aleatoires qui sont de sortie et l'etat de la piscine.
La troisieme souhaite propriete implique que enven si l'entropie recueillies a partir de vos sources est de mauvaise qualite (assez previsible) de la piscine ne doit pas souffrir de la faible entropie et la sortie de nombres aleatoires ne doit montrer aucune preuve de cela.
j'ai teste cet appareil de maniere intensive. La derniere et la plus cruciale du test centre autour de la troisieme propriete. Pour prendre un cas extreme, j'ai commence la piscine avec rien mais des zeros en elle et a genere des '12 MO (100,000,000 bits). J'ai utilise les Irreductibles de la batterie de tests (http://stat.fsu.edu/'geo/diehard.html) et il a passe tous les 15 avec brio... sans recueillir toute l'entropie. Avec cela, je suis satisfait de la du generateur de nombre aleatoire de la performance et de la soumettre a vous de l'utiliser comme une alternative sûre a ce qui est communement observe dans les programmes.
COMMENT CELA FONCTIONNE:
-deux entropie cueilleurs sont crees:
[1] un thread qui suit le mouvement de la souris a des intervalles aleatoires prenant 4bits de l'entropie a partir de la position de la souris et de l'etat du systeme de haute resolution du timer.
[2] un temps de latence de la calculatrice qui obtient 4bits de l'entropie de l'timer haute resolution, lorsqu'il est appele par l'application principale (il est utilise par alling
TKeyGenerator.AddLatency sur l'evenement OnKeyDown d'une zone d'edition, a compter de disque dur de latence, ou irq latence)
Lorsque l'une de l'entropie cueilleurs a accumule 32bits, il l'envoie a l'entropie.
-Le entroyp piscine prend de l'entropie 32bits a un moment et qu'il utilise pour remplir une entropie de la memoire tampon de 256bits, lorsque la memoire est pleine, l'un des principaux reamorçage est execute.
-Le principal reensemencer les mises a jour de la primaire la piscine (un Hash Contexte: etat interne d'une fonction de hachage, avec l'entropie et XORs avec la piscine de semences (cette graine est utilise de la meme façon la façon aleatoire genere randseed). Apres chaque reseed, la graine (avec 256bits de l'entropie) est pret a etre utilise pour generer des nombres aleatoires si l'application appelante desire, mais il continuera a reamorcer et de recueillir de l'entropie quel que soit independamment de ce que. Apres 8 primaire reinitialisations ont eu lieu, un secondaire de reamorçage est execute.
-Le secondaire reensemencer les mises a jour du secondaire de la piscine avec le contenu de la primaire la piscine, puis vide le contenu de la primaire la piscine dans un etat sans l'entropie. Le pool secondaire est persistant en ce qu'il n'est jamais videe et de transporter de l'entropie bits a partir de divers reinitialisations. Un completement nouveau de semences est genere a partir du secondaire reamorçage (ou, comme le primaire sur le modifie avec l'entropie). Cette deuxieme reamorçage empeche le retour en arriere des proprietes (gessing etats precedents de la piscine) et s'assure qu'il existe d'entropie dans la piscine, meme dans des conditions ou la nouvelle entropie est de mauvaise qualite.
-Lorsque l'application appelante doit generer une cle, il appelle SafeGetKey qui assure que pas plus de 8 jeux de 256bits de nombres aleatoires peut etre genere a partir d'un unique effectuer un reamorçage. Pour ce faire, une cle de reserve compteur est incremente a chaque primaire reseed, et ne doit pas depasser 8. Lorsque vous generez un ensemble de nombres aleatoires, la cle de la reserve est decremente et la fonction retournera fasle si la cle de reserve est a 0. REMARQUE: une application peut ignorer la cle de la reserve et de l'appel ForceGetKey. C'est tres pratique risquee et je vous deconseille fortement l'utilisation de cette fonction.
-Le hasard de sortie cree par GetKey est genere avec l'entropie de la piscine, de la graine. La graine est utilisee comme une cle de chiffrement, puis permutees (avec une extension-compression). Les nouvelles graines sont utilisees comme des donnees chiffrees. Il est chiffre avec la precedente semences et elargi compresse en 64 tours. Ces tours s'assurer qu'il est impossible de determiner l'etat de la graine, la primaire la piscine, le pool secondaire ou la entorpy tampon, a son tour, empechant quiconque de trouver le precedent ou suivant les sorties.
REMARQUES:
-Affecter une variable de type TKeyGenerator et de l'appeler .Creer. Cela va demarrer le processus. Lorsque vous avez termine, appel .Destropy.
-Vous pouvez utiliser .KeyCount de determiner l'etat de la cle de reserve (combien de GetKey les appels peuvent etre effectues avant le prochain reamorçage). Je vous tolere l'augmentation de la valeur de MAX_KEY_RESERVE.
-Vous pouvez manipuler la vitesse a laquelle l'entropie recueillies a partir de la souris par la definition de la MOUSE_INTERVAL constante (en milli-secondes). Une valeur inferieure a 10 est obsolete.
-Pas de controle d'erreur est effectue afin de s'assurer d'un haut-compteur de frequence sur le systeme, ce doit etre verifiee par l'application appelante. S'il n'existe pas de compteur, le generateur de nombre aleatoires de travail mais il n'y aura non-aleatoire de nombres.
-La demande doit fournir des 32 OCTETS de la memoire de l'espace dans une variable a transmettre a la GetKey fonctions. Pas de controle d'erreur est fait ici.
-Vous pouvez changer KEY_BUILD_ROUNDS a n'importe quelle valeur superieure ou egale a 32, mais plus de 64 est tout a fait inutile.
/*********************************************************************
/*********************************************************************
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! - REMARQUE IMPORTANTE -
La source soufflet est partie d'une bibliotheque en cours cummulating 3 ans de ma recherche. Si vous voulez l'utiliser dans un programme, un peu de credit, ce serait bien.
NSCrypt.pas contient un generateur de nombre pseudo-aleatoire qui provient d'une source inconnue, et ces implementations de Haval et Rijndael sont [grave] modifications de David Barton est haval.pas et de rijndael.pas trouve dans le DCPcrypt 1.3 composants de la suite.
Telecharger NSCrypt.txt et le renommer NSCrypt.pas (idiot hebergeur), j'ai inclus les fonctions cryptographiques sepperatly parce qu'ils total de 1300 lignes ensemble.
http://www.eccentrix.com/computer/drmungkee/NSCrypt.txt
(le site web reel est www.drmungkee.com)
/*********************************************************************
/*********************************************************************
//vous aurez a traiter avec la documentation ci-dessus.
unite de NoiseSpunge
interface
utilise Windows,les cours,les Controles,les NSCrypt
const
& ! & ! & ! & ! & ! & nbsp SEED_SIZE=8
& ! & ! & ! & ! & ! & nbsp PRIMARY_RESEED=SEED_SIZE
& ! & ! & ! & ! & ! & nbsp SECONDARY_RESEED=SEED_SIZE
& ! & ! & ! & ! & ! & nbsp //parametres
& ! & ! & ! & ! & ! & nbsp MAX_KEY_RESERVE=8
& ! & ! & ! & ! & ! & nbsp KEY_BUILD_ROUNDS=64
& ! & ! & ! & ! & ! & nbsp MOUSE_INTERVAL=10
type
& nbsp & nbsp & nbsp Key256 = array[0..SEED_SIZE-1] de longword
& nbsp & nbsp & nbsp TNoiseSpungeAddEntropy = procedure(Bloc:longword) de l'objet
& nbsp & nbsp & nbsp TNoiseSpungeProcedure = procedure de l'objet
& nbsp & nbsp & nbsp TMouseCollector = (de la classe TThread)
& nbsp & nbsp & nbsp protege
& ! & ! & ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & ! & ! & nbsp x,y:entier
& ! & ! & ! & ! & ! & nbsp Bloc:longword
& ! & ! & ! & ! & ! & nbsp BitsGathered:longword
& ! & ! & ! & ! & ! & nbsp Intervalle,la Frequence,la ThisTime,LastTime:TLargeInteger
& ! & ! & ! & ! & ! & nbsp SendMouseEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Creer
& ! & ! & ! & ! & ! & nbsp procedure SyncSendMouseEntropy
& ! & ! & ! & ! & ! & nbsp procedure Executez remplacer
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TLatencyCollector = classe
& ! & ! & nbsp protege
& ! & ! & ! & ! & ! & nbsp Bloc:longword
& ! & ! & ! & ! & ! & nbsp BitsGathered:longword
& ! & ! & ! & ! & ! & nbsp Temps:TLargeInteger
& ! & ! & ! & ! & ! & nbsp SendLatencyEntropy:TNoiseSpungeAddEntropy
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Creer
& ! & ! & ! & ! & ! & nbsp procedure MeasureLatency
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TEntropyPool = classe
& nbsp & nbsp & nbsp protege
& ! & ! & ! & ! & ! & nbsp Graine:Key256
& ! & ! & ! & ! & ! & nbsp EntropyBuffer:Key256
& ! & ! & ! & ! & ! & nbsp PrimaryPool:Haval_CTX
& ! & ! & ! & ! & ! & nbsp SecondaryPool:Haval_CTX
& ! & ! & ! & ! & ! & nbsp PrimaryReseedCount:octet
& ! & ! & ! & ! & ! & nbsp EntropyCount:byte
& ! & ! & ! & ! & ! & nbsp KeyReserve:octet
& ! & ! & ! & ! & ! & nbsp procedure PermuteSeed
& ! & ! & ! & ! & ! & nbsp procedure PrimaryReseed
& ! & ! & ! & ! & ! & nbsp procedure SecondaryReseed
& ! & ! & ! & ! & ! & nbsp procedure AddEntropy(Bloc:longword)
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp constructeur Creer
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp TKeyGenerator = classe
& nbsp & nbsp & nbsp protege
& ! & ! & ! & ! & ! & nbsp EntropyPool:TEntropyPool
& ! & ! & ! & ! & ! & nbsp MouseCollector:TMouseCollector
& ! & ! & ! & ! & ! & nbsp LatencyCollector:TLatencyCollector
& nbsp & nbsp & nbsp public
& ! & ! & ! & ! & ! & nbsp AddLatency:TNoiseSpungeProcedure
& ! & ! & ! & ! & ! & nbsp constructeur Creer
& ! & ! & ! & ! & ! & nbsp destructeur de Detruire remplacer
& ! & ! & ! & ! & ! & nbsp fonction KeyCount:octet
& ! & ! & ! & ! & ! & nbsp fonction SafeGetKey(var Key):boolean
& ! & ! & ! & ! & ! & nbsp procedure ForcedGetKey(var Key)
& nbsp & nbsp & nbsp fin
application
constructeur TMouseCollector.Creer
begin
& nbsp & nbsp & nbsp herite de Creer(true)
& nbsp & nbsp & nbsp Aleatoire
& nbsp & nbsp & nbsp PrngInit(@PCtx,RandSeed)
& nbsp & nbsp & nbsp FreeOnTerminate:=true
& nbsp & nbsp & nbsp Priorite:=tpNormal
& nbsp & nbsp & nbsp Cv
fin
procedure TMouseCollector.SyncSendMouseEntropy
begin
& nbsp & nbsp & nbsp SendMouseEntropy(Bloc)
fin
procedure TMouseCollector.executer
var NilHandle:pointeur
& ! & ! & ! & nbsp Ralenti:boolean
begin
& nbsp & nbsp & nbsp NilHandle:=nil
& nbsp & nbsp & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp Ralenti:=false
& nbsp & nbsp & nbsp QueryPerformanceFrequency(Frequence)
& nbsp & nbsp & nbsp repeat
& ! & ! & ! & ! & ! & nbsp si Inactif=false then
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp MsgWaitForMultipleObjects(0,NilHandle,faux,MOUSE_INTERVAL,0)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp Ralenti:=true
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(ThisTime)
& ! & ! & ! & ! & ! & nbsp si ThisTime-LastTime>Intervalle puis
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp si (x<>de la souris.cursorpos.x)et(y<>de la souris.cursorpos.y) puis
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp x:=mouse.cursorpos.x
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp y:=mouse.cursorpos.y
& ! & ! & ! & ! & ! & ! & nbsp & ! & ! & ! & ! & nbsp Inc(Bloc,(((x et 15)xor(y et 15))xor(ThisTime et 15))shl
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp BitsGathered)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Inc(BitsGathered,4)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp si BitsGathered=32
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@PCtx,Bloc)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Synchroniser(SyncSendMouseEntropy)
& ! & ! & ! & ! & ! & ! & ! & nbsp - ! & ! & ! & ! & ! & ! & nbsp Bloc:=0
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp BitsGathered:=0
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Intervalle:=(((( Prng(@PCtx) mod MOUSE_INTERVAL) div 2) MOUSE_INTERVAL)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp *Frequence)div 1000
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(LastTime)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Arretes:=false
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin else
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp QueryPerformanceCounter(LastTime)
& ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & ! & nbsp Ralenti:=false
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp fin
& nbsp & nbsp & nbsp jusqu'a sa Resiliation=true
fin
constructeur TLatencyCollector.Creer
begin
& nbsp & nbsp & nbsp herite de Creer
& nbsp & nbsp & nbsp Bloc:=0
& nbsp & nbsp & nbsp BitsGathered:=0
fin
procedure TLatencyCollector.MeasureLatency
begin
& nbsp & nbsp & nbsp QueryPerformanceCounter(Temps)
& nbsp & nbsp & nbsp Inc(Bloc,(Temps et 15)shl BitsGathered)
& nbsp & nbsp & nbsp Inc(BitsGathered,4)
& nbsp & nbsp & nbsp si BitsGathered=32
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp SendLatencyEntropy(Bloc)
& ! & ! & ! & ! & ! & nbsp Bloc:=0
& ! & ! & ! & ! & ! & nbsp BitsGathered:=0
& nbsp & nbsp & nbsp fin
fin
constructeur TEntropyPool.Creer
begin
& nbsp & nbsp & nbsp herite de Creer
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp HavalInit(@SecondaryPool)
& nbsp & nbsp & nbsp FillChar(Semences,SizeOf(Graine),0)
& nbsp & nbsp & nbsp EntropyCount:=0
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
& nbsp & nbsp & nbsp KeyReserve:=0
fin
procedure TEntropyPool.PermuteSeed
var TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i:byte
begin
& nbsp & nbsp & nbsp for i:=De 0 a SEED_SIZE-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp PrngInit(@PCtx,des Semences[i])
& ! & ! & ! & ! & ! & nbsp TempBuffer[0,i]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp TempBuffer[1,i]:=Prng(@PCtx)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp HavalInit(@HCtx)
& nbsp & nbsp & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& nbsp & nbsp & nbsp HavalOutput(@HCtx,Semences)
fin
procedure TEntropyPool.PrimaryReseed
var TempSeed:Key256
& ! & ! & ! & nbsp i:byte
begin
& nbsp & nbsp & nbsp HavalUpdate(@PrimaryPool,EntropyBuffer,SizeOf(EntropyBuffer))
& nbsp & nbsp & nbsp si PrimaryReseedCount
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp HavalOutput(@PrimaryPool,TempSeed)
& ! & ! & ! & ! & ! & nbsp for i:=0 to SEED_SIZE-1 ne Semences[i]:=Semences[i] xor TempSeed[i]
& ! & ! & ! & ! & ! & nbsp Inc(PrimaryReseedCount)
& nbsp & nbsp & nbsp fin d'autre SecondaryReseed
& nbsp & nbsp & nbsp FillChar(EntropyBuffer,SizeOf(EntropyBuffer),0)
& nbsp & nbsp & nbsp si KeyReserve
& nbsp & nbsp & nbsp EntropyCount:=0
fin
procedure TEntropyPool.SecondaryReseed
begin
& nbsp & nbsp & nbsp HavalOutput(@PrimaryPool,Semences)
& nbsp & nbsp & nbsp HavalUpdate(@SecondaryPool,Semences,SizeOf(Semences))
& nbsp & nbsp & nbsp HavalOutput(@SecondaryPool,Semences)
& nbsp & nbsp & nbsp PermuteSeed
& nbsp & nbsp & nbsp HavalInit(@PrimaryPool)
& nbsp & nbsp & nbsp PrimaryReseedCount:=0
fin
procedure TEntropyPool.AddEntropy(Bloc:longword)
begin
& nbsp & nbsp & nbsp Deplacer(Bloc,pointeur(longword(@EntropyBuffer) (EntropyCount*SizeOf(Bloc)))^,SizeOf(Bloc))
& nbsp & nbsp & nbsp Inc(EntropyCount,1)
& nbsp & nbsp & nbsp si EntropyCount=PRIMARY_RESEED puis PrimaryReseed
fin
constructeur TKeyGenerator.Creer
begin
& nbsp & nbsp & nbsp herite de Creer
& nbsp & nbsp & nbsp EntropyPool:=TEntropyPool.Creer
& nbsp & nbsp & nbsp MouseCollector:=TMouseCollector.Creer
& nbsp & nbsp & nbsp MouseCollector.SendMouseEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp LatencyCollector:=TLatencyCollector.Creer
& nbsp & nbsp & nbsp LatencyCollector.SendLatencyEntropy:=EntropyPool.AddEntropy
& nbsp & nbsp & nbsp AddLatency:=LatencyCollector.MeasureLatency
fin
destructeur TKeyGenerator.Detruire
begin
& nbsp & nbsp & nbsp MouseCollector.resilier
& nbsp & nbsp & nbsp LatencyCollector.detruire
& nbsp & nbsp & nbsp EntropyPool.detruire
& nbsp & nbsp & nbsp herite de Detruire
fin
fonction de TKeyGenerator.KeyCount:octet
begin
& nbsp & nbsp & nbsp Resultat:=EntropyPool.KeyReserve
fin
fonction de TKeyGenerator.SafeGetKey(var Key):boolean
var TempSeed:Key256
& ! & ! & ! & nbsp TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp RCtx:Rijndael_CTX
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i,j:byte
begin
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve=0, alors
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp Sortie
& ! & ! & ! & ! & ! & nbsp Result:=false
& nbsp & nbsp & nbsp fin else Result:=true
& nbsp & nbsp & nbsp Deplacer(EntropyPool.Semences,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Graine)
& nbsp & nbsp & nbsp for i:=0 to KEY_BUILD_ROUNDS-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& ! & ! & ! & ! & ! & nbsp pour j:=0 pour SEED_SIZE-1 do
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@pctx,TempSeed[j])
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp HavalInit(@HCtx)
& ! & ! & ! & ! & ! & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& ! & ! & ! & ! & ! & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp Deplacer(TempSeed,Cle,SizeOf(TempSeed))
& nbsp & nbsp & nbsp Dec(EntropyPool.KeyReserve,1)
fin
procedure TKeyGenerator.ForcedGetKey(var Key)
var TempSeed:Key256
& ! & ! & ! & nbsp TempBuffer:array[0..1]de Key256
& ! & ! & ! & nbsp PCtx:Prng_CTX
& ! & ! & ! & nbsp HCtx:Haval_CTX
& ! & ! & ! & nbsp i,j:octet
begin
& nbsp & nbsp & nbsp Deplacer(EntropyPool.Semences,TempSeed,SizeOf(TempSeed))
& nbsp & nbsp & nbsp EntropyPool.PermuteSeed
& nbsp & nbsp & nbsp RijndaelInit(@RCtx,EntropyPool.Graine)
& nbsp & nbsp & nbsp for i:=0 to KEY_BUILD_ROUNDS-1 do
& nbsp & nbsp & nbsp commencer
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[0])
& ! & ! & ! & ! & ! & nbsp RijndaelEncrypt(@RCtx,TempSeed[4])
& ! & ! & ! & ! & ! & nbsp pour j:=0 pour SEED_SIZE-1 do
& ! & ! & ! & ! & ! & nbsp commencer
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp PrngInit(@pctx,TempSeed[j])
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[0,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & ! & ! & ! & nbsp TempBuffer[1,j]:=Prng(@PCtx)
& ! & ! & ! & ! & ! & nbsp fin
& ! & ! & ! & ! & ! & nbsp HavalInit(@HCtx)
& ! & ! & ! & ! & ! & nbsp HavalUpdate(@HCtx,TempBuffer,SizeOf(TempBuffer))
& ! & ! & ! & ! & ! & nbsp HavalOutput(@HCtx,TempSeed)
& nbsp & nbsp & nbsp fin
& nbsp & nbsp & nbsp Deplacer(TempSeed,Cle,SizeOf(TempSeed))
& nbsp & nbsp & nbsp si EntropyPool.KeyReserve<0 alors Dec(EntropyPool.KeyReserve,1)
fin
a la fin.
(C)Copyright DrMungkee, 2001 (www.drmungkee.com, [email protected])
Chiffrement des nombres aléatoires
By commentfaire
Chiffrement des nombres aléatoires : Plusieurs milliers de conseils pour vous faciliter la vie.