C ++ Crypto: Bölüm 3-pbkdf2

Aug 26 2020

Modern Crypto kitaplıklarını araştırmak.
İyi bir şey bulamadım.

Muhtemelen bunu yanlış yaptığımı biliyorum, bu yüzden burada çalışın. Birbiri üzerine inşa edilen dört yapı için dört farklı inceleme olacak:

  1. Hashing
  2. Hashed Anahtar
  3. Şifre Anahtarı
  4. Tuzlu Meydan Okuma Yanıtı

Bu inceleme, pbkdf2 uygulamasının bir uygulaması içindir. Bu, arızalarda hash oluşturmak için aşamalı olarak daha pahalı hale getirmenize izin veren HMAC kullanmanın bir yoludur. Buradaki fikir, çok sayıda tahmin yapmayı zorlaştırarak saldırıları yavaşlatabilmenizdir.

Bu sorularda sunulan veri yapıları ve uygulama, RFC2104'e ve kod projesiyle ilgili bu gönderiye dayanmaktadır .

Kullanım Örneği

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

Yanıtlar

1 user673679 Nov 16 2020 at 03:47
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)

"A longan intve a std::size_thepsi bir bara girdi ..." hepsi olamaz std::size_tmı?

Ayrıca, loopdeğişkeni geçersiz kılmak gereksiz yere kafa karıştırıcıdır.


    std::copy(std::begin(tmp), std::end(tmp), std::begin(digest));

Bunun digest = tmp;uygun bir atama operatörü ile olabileceğini hissediyorum .


salt + "\x00\x00\x00\x01"s

Bu, adlandırılmış bir sabit (veya hatta adlandırılmış bir işlev) olabilir mi? Ya da bunun neden burada olduğunu açıklamak için bir yorum ekleyebilirsiniz.


            digest[loop] = digest[loop] ^ tmp[loop];

Nitpick: kullanabilir ^=


Belki de çıktı bir referansa yazılmayan bir dönüş değeri olmalıdır?


Bunun algoritma / güvenlik yönlerini değerlendirmek için kriptografi / güvenlik hakkında yeterince bilgim yok.