C ++ Crypto: ตอนที่ 3-pbkdf2
กำลังมองหาห้องสมุด Crypto ที่ทันสมัย
ไม่พบสิ่งที่ดี
ฉันรู้ว่าฉันอาจจะทำผิดทั้งหมดจึงทำงานกับฉันที่นี่ จะมีบทวิจารณ์ที่แตกต่างกันสี่แบบสำหรับโครงสร้างสี่แบบที่สร้างต่อกัน:
- แฮช
- แฮชคีย์
- รหัสผ่าน
- การตอบสนองความท้าทายเค็ม
บทวิจารณ์นี้มีไว้สำหรับการนำไปใช้งาน pbkdf2 นี่เป็นวิธีการใช้ HMAC ที่ช่วยให้คุณสามารถสร้างแฮชได้ในราคาแพงขึ้นทีละน้อย แนวคิดก็คือคุณสามารถชะลอการโจมตีได้โดยการคาดเดาจำนวนมากให้ยากขึ้น
โครงสร้างข้อมูลและการดำเนินงานที่นำเสนอในคำถามเหล่านี้จะขึ้นอยู่กับRFC2104และโพสต์ในcodeproject
ตัวอย่างการใช้งาน
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
คำตอบ
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)
"เป็นและทั้งหมดเดินเข้าไปในบาร์ ..." ไม่พวกเขาทั้งหมดจะเป็น?longintstd::size_tstd::size_t
นอกจากนี้การลบล้างloopตัวแปรยังทำให้สับสนโดยไม่จำเป็น
std::copy(std::begin(tmp), std::end(tmp), std::begin(digest));
ฉันรู้สึกว่าสิ่งนี้สามารถใช้ได้digest = tmp;กับผู้ดำเนินการมอบหมายงานที่เหมาะสม
salt + "\x00\x00\x00\x01"s
นี่อาจเป็นค่าคงที่ที่ตั้งชื่อ (หรือแม้กระทั่งฟังก์ชันที่มีชื่อ)? หรืออาจเพิ่มความคิดเห็นเพื่ออธิบายว่าเหตุใดจึงมาที่นี่
digest[loop] = digest[loop] ^ tmp[loop];
Nitpick: สามารถใช้ได้ ^=
บางทีผลลัพธ์ควรเป็นค่าส่งกลับไม่ใช่เขียนอ้างอิง?
ฉันไม่รู้เพียงพอเกี่ยวกับการเข้ารหัส / ความปลอดภัยเพื่อประเมินอัลกอริทึม / แง่มุมด้านความปลอดภัยของสิ่งนี้