2017-06-05 2 views
0

J'ai un projet Web API où, dans l'un des points d'extrémité, j'utilise la bibliothèque Bouncy Castle pour générer des paires de clés RSA. Tout en faisant des tests de charge j'ai commencé à obtenir 504 (erreur de timeout) après dire 1500 demandes parallèles à mon API Web. Après quelques recherches, j'ai réalisé que c'était Bouncy Castle qui le provoquait. Alors maintenant je pense à précharger une table avec disons 1 million de paires de clés RSA et les obtenir de cette table quand j'en ai besoin. Voici mon code où je suis générer keypair en utilisant BC:Bouncy Castle prend beaucoup de temps pour générer une paire de clés RSA

var r = new RsaKeyPairGenerator(); 
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); 
var keyPair = r.GenerateKeyPair(); 
var publicKey = string.Empty; 
using (var stream = new MemoryStream()) 
{ 
    var textWriter = new StreamWriter(stream); 
    var pemWriter = new PemWriter(textWriter); 
    pemWriter.WriteObject(keyPair.Public); 
    pemWriter.Writer.Flush(); 
    stream.Position = 0; 
    var sr = new StreamReader(stream); 
    publicKey = sr.ReadToEnd(); 
    textWriter.Close(); 
} 

var privateKey = string.Empty; 
using (var stream = new MemoryStream()) 
{ 
    var textWriter = new StreamWriter(stream); 
    var pemWriter = new PemWriter(textWriter); 
    pemWriter.WriteObject(keyPair.Private); 
    pemWriter.Writer.Flush(); 

    stream.Position = 0; 
    var sr = new StreamReader(stream); 
    privateKey = sr.ReadToEnd(); 
    textWriter.Close(); 
} 

donc quelques questions, est-ce que je fais mal dans le code ci-dessus (il fonctionne très bien, mais s'il y a quelque chose que je fais ce qui est peut-être causant le retard et peut être évité)? Aussi, si je vais avec l'autre approche (préchargement de la table SQL avec 1 million de paires de clés), quel serait le meilleur moyen de peupler la table avec 1 million d'enregistrements? (de préférence en utilisant ADO .net)

+0

Il va s'aggraver car une clé de 2048 bits est recommandée sur 1024 bits. Essayez peut-être de le faire via RSACryptoServiceProvider() -> ExportParameters() de .Net pour comparer car l'implémentation sera différente. –

+0

Je vais essayer de voir si RSACryptoServiceProvider fait une différence. Merci – tavier

Répondre

1

Si le générateur de clés fait du bon travail, il utilisera un générateur de nombres aléatoires à forte entropie. Ceux-ci essaieront de rassembler un maximum d'aléas «externes» de votre serveur, et un bon générateur s'arrêtera et fera peut-être une estimation de l'aléatoire recueilli. Les sources d'aléas (si vous n'avez pas de matériel spécifique disponible) sont les entrées utilisateur, les événements matériels (tels que le trafic réseau et l'interruption USB) et la gigue du minuteur (qui peut changer lorsque les horloges du CPU changent) .

Sur un serveur, il peut être difficile de rassembler suffisamment d'entropie pour générer de bonnes clés (en raison du manque d'entrée utilisateur et d'un nombre réduit de périphériques).

Essayer de générer un très grand nombre de clés sans matériel spécial va donc être soit lent ou de mauvaise qualité.

Une source matérielle (telle que http://onerng.info/) serait préférable dans ce cas.

+0

"Essayer de générer un très grand nombre de clés sans matériel spécial va donc être lent ou de mauvaise qualité." Cette déclaration est beaucoup plus forte que ce qui est justifié. Il n'est pas du tout au-delà de l'état de l'art "de générer un très grand nombre de clés RSA" d'excellente qualité et de rapidité raisonnable sans matériel particulier. –

+0

Une nouvelle SecureRandom() est créée à chaque fois et chaque partie sera ensemencée en partie par 32 octets de RNGCryptoServiceProvider. Peut-être que quelqu'un d'autre sait si cela va épuiser une piscine d'entropie ou non. –

+0

Donc, selon mes découvertes, il faut beaucoup de temps pour générer environ 10k touches (environ 25 minutes), mais le temps nécessaire n'augmente pas avec le temps. Cela prend toujours entre 10 millisecondes et 700 millisecondes (cela ne dépend pas de savoir si c'est la première clé générée ou la dernière dans la boucle). J'ai posté une question distincte ici: https://stackoverflow.com/questions/44386101/how-to-fasten-rsa-key-pair-generation-process – tavier