Question

Historique

Je suis la conception d'un système qui permet le développement des systèmes d'authentification dynamique pour un utilisateur de contenu Web statique. La motivation est de pré-générer de grandes quantités de contenu web complexe à générer, mais sensible, puis servir statiquement avec basée sur les cookies (intégration des informations de façon réversible crypté) l'authentification en place, exécutée par le serveur web inately. L'utilisation d'un cryptage en mode AEAD primitive.

Le problème

Je dois générer de IVEC et les clés qui sont valables pour une durée de temps, disons une semaine (la paire actuelle valide). et que le passé IVECs / Les clés sont également valables pour dire 2 semaines (historiquement valide) et toutes les données cryptées avec les secrets historiquement valides sera juste rechiffrés avec le IVEC / KEY actuelle valide.

Ce que je besoin est un CSPRNG déterministe que les graines d'un nombre aléatoire et un mot de passe et qui peut produire de façon indexée 64 bits ou des blocs de 128 bits de numéros. Si j'utilise une semaine-depuis- « 1 janvier 1970 », comme l'un des éléments d'index de mon CSPRNG hypothétique je devrais être en mesure de construire un système qui change automatiquement les clés comme naturellement le temps passe.

L'approche que je considère

Maintenant, je ne vois pas une telle fonctionnalité dans cryptopp, ou je ne sais maintenant la terminologie assez bien, et comme cryptopp est le plus avancé des bibliothèques de cryptage là-bas, je n'ai pas confiance que je vais trouver un autre. Donc, si je ne trouve pas une mise en œuvre là-bas, je rouler mon propre. Est-ce que la génération d'une structure de chaîne statique sur des données concatinated puis le hachant (ci-dessous) faire l'affaire?

RIPEMD160 (RandomPreGeneratedFixedNonce: PassPhrase: UInt64SinceEpoch: 128BitBlockIndexNumber);

Note: Les blocknumbers sera assigné et avoir une structure régulière, donc par exemple pour un produit de digestion de 128 bits, les 64 premiers bits du bloc 0 seront pour la IVEC, et l'ensemble de l'élément 1 pour le 128-bit clé.

Est-ce une approche sonore (-. I.e., sécuriser cryptographiquement)?

- modifier: après accepter un commentaire -

Après réflexion, j'ai décidé de fusionner ce que je l'origine considéré comme le mot de passe et le nonce / sel dans un 16 octets (cryptographicall fort) touche et utiliser les techniques décrites dans le PKCS # 5 à Derive multiples en fonction du temps clés. Il n'y a pas besoin d'un sel, comme les phrases secrètes ne sont pas utilisés.

Était-ce utile?

La solution

Question intéressante.

Tout d'abord, vos vecteurs initiaux ne doivent pas être des quantités aléatoires cryptographiquement fortes, mais devrait être par message unique. Le IV est vraiment juste une sorte de valeur de sel qui assure que les messages similaires chiffrés en utilisant la même clé ne pas voir similaire une fois qu'ils sont cryptées. Vous pouvez utiliser un générateur pseudo-aléatoire rapide pour générer le IV, puis l'envoyer (de préférence crypté) ainsi que les données chiffrées.

Les touches, bien sûr, devrait être aussi fort que vous pouvez pratiquement les faire.

Votre proposition de hachage d'une chaîne de texte contenant un nonce, mot de passe et les données de validité me semble très raisonnable - il est globalement conforme à ce qui se fait par un autre système qui utilisent un mot de passe pour générer une clé. Vous devez hachage plus plusieurs fois - pas seulement une fois - pour rendre la génération de clés informatiquement coûteuse (qui sera un plus gros problème pour quiconque tente de force brute la clé que ce sera pour vous)

.

Vous pouvez également jeter un oeil au système clé génération mis en PKCS # 5 (par exemple http://www.faqs.org/rfcs/rfc2898.html ) qui est mis en œuvre cryptopp comme PasswordBasedKeyDerivationFunction. Ce mécanisme est déjà largement utilisé et connu pour être sûr raisonnable (notez que PKCS # 5 recommande hachant les données de passphrase au moins 1000 fois). Vous pouvez simplement ajouter votre période de validité et les données d'index pour le mot de passe et l'utilisation PasswordBasedKeyDerivationFunction tel qu'il est.

Vous ne dites pas ce que l'algorithme de cryptage vous propose d'utiliser pour chiffrer les données, mais je suggère que vous devriez choisir quelque chose largement utilisé et connu pour être sûr ... et en particulier, je vous suggère que vous utilisez AES. Je suggère également d'utiliser l'une des fonctions digest SHA (peut-être comme une entrée à PasswordBasedKeyDerivationFunction). SHA-2 est en cours, mais SHA-1 est suffisante à des fins de génération de clés.

Vous aussi ne dites pas ce que la longueur de clé que vous cherchez à générer, mais vous devez savoir que la quantité d'entropie dans vos clés dépend de la longueur de la phrase que vous utilisez, et à moins que le mot de passe est très longue qui sera beaucoup moins que le keylength exige idéalement.

Le maillon le plus faible dans ce schéma est le mot de passe lui-même, et qui est toujours va limiter le niveau de sécurité que vous pouvez achive. Tant que vous salez vos données (comme vous faites) et faites la génération de clé coûteuse pour ralentir les attaques par force brute, vous devriez être bien.

Autres conseils

  

Ce que je besoin est un CSPRNG déterministe que les graines d'un nombre aléatoire et un mot de passe et qui peut produire de façon indexée 64 bits ou des blocs de 128 bits de numéros. Si j'utilise une semaine-depuis- « 1 jan 1970 » comme l'un des éléments d'index de mon CSPRNG hypothétique je devrais être en mesure de construire un système qui change automatiquement les clés comme naturellement le temps passe.

Je pense une partie de la solution consiste à utiliser un générateur à base non temps. De cette façon, si les deux parties commencent par la même graine, ils produisent à la fois le même flux aléatoire. Vous pouvez superposer votre logique « semaines depuis la semaine 1, 1970 » au-dessus de cela.

Pour ce faire, vous devez utiliser OFB_mode<T>::Encryption. Il peut être utilisé comme un générateur, car le mode OFB utilisations AdditiveCipherTemplate<T>, qui dérive de RandomNumberGenerator.

En fait, Crpyto ++ utilise le générateur test.cpp de sorte que les résultats peuvent être reproduits si quelque chose échoue. Voici comment vous pouvez utiliser OFB_mode<T>::Encryption. Il applique également CTR_Mode<T>::Encryption:

SecByteBlock seed(32 + 16);
OS_GenerateRandomBlock(false, seed, seed.size());

for(unsigned int i = 0; i < 10; i++)
{
    OFB_Mode<AES>::Encryption prng;
    prng.SetKeyWithIV(seed, 32, seed + 32, 16);

    SecByteBlock t(16);
    prng.GenerateBlock(t, t.size());

    string s;
    HexEncoder hex(new StringSink(s));

    hex.Put(t, t.size());
    hex.MessageEnd();

    cout << "Random: " << s << endl;
}

L'appel à des extractions de OS_GenerateRandomBlock octets de /dev/{u|s}random et utilise ensuite que comme une semence commune simulée. Chaque exécution du programme sera différent. Au sein de chaque exécution du programme, il imprime semblable au suivant:

$ ./cryptopp-test.exe
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD
Random: DF3D3F8E8A21C39C0871B375013AA2CD

Il y a un autre générateur disponible qui fait la même chose, mais sa ne fait pas partie de la bibliothèque Crypto ++. Son appelé AES_RNG, et son basé sur AES-256. Sa tête que la mise en œuvre, et vous pouvez le trouver à la Crypto ++ wiki sous RandomNumberGenerator .

Voir aussi le sujet Reproductibilité pour la classe RandomNumberGenerator sur le wiki du Crypto.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top