Crypto C ++: Partie 3-pbkdf2
À la recherche de bibliothèques Crypto modernes.
Je n'ai rien trouvé de bon.
Je sais que j'ai probablement mal fait tout cela, alors travaillez avec moi ici. Il y aura quatre revues différentes pour quatre structures qui s'appuient les unes sur les autres:
- Hashing
- Clé hachée
- Clé de mot de passe
- Réponse au défi salé
Cette revue concerne une implémentation de l'implémentation pbkdf2. C'est une façon d'utiliser HMAC qui vous permet de rendre progressivement plus cher la création du hachage en cas d'échec. L'idée est que vous pouvez ralentir les attaques en rendant plus difficile de faire beaucoup de suppositions.
Les structures de données et l'implémentation présentées dans ces questions sont basées sur RFC2104 et cet article sur codeproject .
Exemple d'utilisation
Digest<Pbkdf2<HMac<Sha1>>> digest;
Pbkdf2<HMac<Sha1>> pbkdf2;
pbkdf2.hash("The password", "A Salt", 2048, digest);
pbkdf2.h
#ifndef THORS_ANVIL_CRYPTO_PBKDF2_H
#define THORS_ANVIL_CRYPTO_PBKDF2_H
#include "hmac.h"
#include <string>
// RFC-2898 PKCS #5: Password-Based Cryptography Specification Version 2.0
namespace ThorsAnvil::Crypto
{
// Look in hmac.h for good examples of PRF
// ThorsAnvil::Crypto::HMac
template<typename PRF>
struct Pbkdf2
{
static constexpr std::size_t digestSize = PRF::digestSize;
using DigestStore = typename PRF::DigestStore;
void hash(std::string const& password, std::string const& salt, long iter, DigestStore& digest)
{
#pragma vera-pushoff
using namespace std::string_literals;
#pragma vera-pop
PRF prf;
DigestStore tmp;
prf.hash(password, salt + "\x00\x00\x00\x01"s, tmp);
std::copy(std::begin(tmp), std::end(tmp), std::begin(digest));
for (int loop = 1; loop < iter; ++loop)
{
prf.hash(password, tmp.view(), tmp);
for (std::size_t loop = 0; loop < digestSize; ++loop)
{
digest[loop] = digest[loop] ^ tmp[loop];
}
}
}
};
}
#endif
Réponses
void hash(std::string const& password, std::string const& salt, long iter, DigestStore& digest)
...
for (int loop = 1; loop < iter; ++loop)
...
for (std::size_t loop = 0; loop < digestSize; ++loop)
"Un longan intet un std::size_ttous sont entrés dans un bar ..." ne pourraient-ils pas tous être std::size_t?
En outre, le remplacement de la loopvariable est inutilement déroutant.
std::copy(std::begin(tmp), std::end(tmp), std::begin(digest));
J'ai l'impression que cela pourrait simplement être digest = tmp;avec un opérateur d'affectation approprié.
salt + "\x00\x00\x00\x01"s
Cela pourrait-il être une constante nommée (ou même une fonction nommée)? Ou peut-être ajouter un commentaire pour expliquer pourquoi c'est ici.
digest[loop] = digest[loop] ^ tmp[loop];
Nitpick: pourrait utiliser ^=
Peut-être que la sortie devrait être une valeur de retour, pas écrite dans une référence?
Je ne connais pas assez la cryptographie / la sécurité pour en évaluer les aspects algorithme / sécurité.