ฉันสามารถใช้ตัวจัดสรรที่กำหนดเองสำหรับ std :: array สำหรับคีย์การเข้ารหัสที่ปลอดภัยได้หรือไม่


9

ฉันรู้ว่าstd::arrayจัดสรรอย่างสมบูรณ์ในสแต็ก แต่คำถามนี้ได้รับแรงบันดาลใจจากความกังวลด้านความปลอดภัยที่ต้องการสองสิ่ง:

  1. ข้อมูลในstd::arrayจะถูก zerod หรือสุ่มเมื่อถูกทำลาย
  2. ข้อมูลในstd::arrayจะถูกล็อคเพื่อไม่ให้ไปที่ดิสก์ไม่ว่าจะเกิดข้อผิดพลาดหรือในหน่วยความจำสลับ

มักจะมีstd::vectorวิธีการแก้ปัญหาคือการสร้างจัดสรรที่กำหนดเองที่ทำสิ่งเหล่านี้ อย่างไรก็ตามสำหรับstd::arrayฉันไม่เห็นวิธีการทำเช่นนี้และด้วยเหตุนี้คำถามนี้

สิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือ:

template <typename T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
    static_assert(std::is_pod<T>::value, "Only POD types allowed")
    static_assert(sizeof(T) == 1, "Only 1-byte types allowed")
    virtual ~SecureArray()
    {
        std::vector<uint8_t> d = RandomBytes(Size); // generates Size random bytes
        std::memcpy(this->data(), d.data(), Size);
    }
}

แต่สิ่งนี้ชัดเจนว่าขาดการล็อคหน่วยความจำและทำให้รูปแบบการทำงานstd::arrayนั้นซับซ้อนขึ้นโดยการใช้std::arrayในตอนแรก

มีวิธีแก้ปัญหาที่ดีกว่านี้ไหม?


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
ซามูเอล Liew

ขออภัยนั่นคือสำหรับ mods; อีกอันคือโมเดอเรเตอร์ที่ปฏิเสธธงไม่ใช่คุณ สิ่งเดียวที่คุณทำได้คือการระบุว่าคำตอบนั้นถูกต้องหรือไม่ดังนั้นฉันจึงสามารถกำหนดเงินรางวัลให้กับสิ่งที่ดีที่สุด ฉันสามารถประเมินตนเองได้ แต่ฉันไม่ใช่ผู้เชี่ยวชาญที่เก่ง เหตุผลที่ทำให้รางวัลนั้นหายไปเมื่อได้รับมอบหมาย
Maarten Bodewes

@ Maarten-reinstateMonica น่าเสียดายที่ไม่มีคำตอบในการแก้ปัญหาอย่างสะอาด
นักฟิสิกส์ควอนตัม

@TheQuantumPhysicist อะไรที่จะได้รับการพิจารณาว่าเป็นวิธีที่สะอาด? คุณสามารถลองและทำให้ข้อกำหนดเหล่านั้นชัดเจนหรือไม่? ที่ช่วยคิดเกี่ยวกับทางออกที่เป็นไปได้เช่นกัน ฉันคิดว่าฉันอาจรู้ว่าคุณหมายถึงอะไร แต่ฉันก็คิดว่าคุณน่าจะแม่นยำกว่านี้
Maarten Bodewes

@ Maarten-reinstateMonica การใช้ตัวจัดสรรที่เรามีอยู่แล้วในทางใดทางหนึ่ง สิ่งที่เขียนใหม่ตั้งแต่ต้นเป็นความคิดที่ไม่ดีและจะต้องมีการทดสอบ นั่นควรจะเป็นทางเลือกสุดท้าย คำตอบด้านล่างคือการแนะนำวิธีแก้ปัญหาที่ชัดเจนซึ่งฉันได้กล่าวไปแล้วว่าฉันหลีกเลี่ยงในการแสดงความคิดเห็น (ก่อนที่จะย้ายไปแชท)
นักฟิสิกส์ควอนตัม

คำตอบ:


5

std::arrayไม่สามารถใช้ตัวจัดสรร อย่างไรก็ตามดูเหมือนว่าคลาส SecureArray ของคุณจะสามารถบรรลุสิ่งที่คุณต้องการผ่าน Constructor / Deconstructor ที่กำหนดเอง

บางสิ่งเช่นนี้

#include <sys/mman.h>

template<class T, std::size_t Size>
struct SecureArray : public std::array<T, Size>
{
    // Your static_asserts...

    SecureArray(void) {
        mlock(std::array<T, Size>::data(), sizeof(T) * Size);
    }

    ~SecureArray(void) {
        char *bytes = reinterpret_cast<char *>(std::array<T, Size>::data());
        for (std::size_t i = 0; i < sizeof(T) * Size; i++)
            bytes[i] = 0;
        munlock(bytes, sizeof(T) * N);
    }
};

4

ฉันรู้ว่าstd::arrayจัดสรรอย่างสมบูรณ์ในสแต็ก

สิ่งนี้ไม่เป็นความจริงเลย std::arrayไม่ได้จัดสรรหน่วยความจำใด ๆ ดังนั้นจึงขึ้นอยู่กับว่าคุณจัดสรรไว้ที่ไหน

auto* arr = new std::array<int, 100>(); // BUM! it is allocated on the heap

แต่สิ่งนี้ชัดเจนว่าขาดการล็อคหน่วยความจำและทำให้รูปแบบการทำงานstd::arrayนั้นซับซ้อนขึ้นโดยการใช้std::arrayในตอนแรก

ประการแรกไม่มีปัญหาในการล็อคหน่วยความจำบนสแต็ก ดูตัวอย่าง POSIX:

#include <iostream>
#include <sys/mman.h>
#include <array>

int main()
{
    std::array<int, 3> a = {1, 2, 3};        // std::array allocated on the stack
    if (mlock(a.data(), sizeof(a)) == 0)
    {
        std::cout << "LOCKED" << std::endl;
    }
}

ดังนั้นคุณสามารถโทรmlockหรืออะนาล็อกพกพาใด ๆ ในตัวSecureArrayสร้าง

ประการที่สองคุณคาดหวังว่าจะได้รับประสิทธิภาพอะไร ความเร็วในการอ่าน / เขียนหน่วยความจำไม่ได้ขึ้นอยู่กับว่าคุณจัดสรรอาเรย์ของคุณไว้ที่ฮีปหรือสแต็ค ดังนั้นจึงเป็นเรื่องเกี่ยวกับความเร็วที่คุณสามารถจัดสรรและล็อคหน่วยความจำ หากประสิทธิภาพมีความสำคัญการล็อคหน่วยความจำอาจช้าเกินไป (หรือไม่ใครรู้?) ที่จะเรียกมันทุกครั้งในตัวSecureArrayสร้างแม้ว่าหน่วยความจำจะถูกจัดสรรบนสแต็ก

ดังนั้นจึงสะดวกกว่าที่จะใช้std::vectorกับตัวจัดสรรที่กำหนดเอง มันอาจทำการจัดสรรล่วงหน้าและเตรียมหน่วยความจำขนาดใหญ่ล่วงหน้าดังนั้นความเร็วในการจัดสรรจะใกล้เคียงกับความเร็วในสแต็ก


มันไม่เกี่ยวกับความเร็วเลยมันเกี่ยวกับความปลอดภัยและตรวจสอบให้แน่ใจว่าสิ่งต่าง ๆ ไม่ได้ถูกเคลื่อนย้ายเพราะโดยทั่วไปแล้วหมายถึงการทำสำเนา
Maarten Bodewes

2
@ Maarten-reinstateMonica อืม ... ดูเหมือนว่าฉันไม่ได้ตั้งใจที่จะใช้std::arrayแทนที่จะstd::vectorเป็นที่แรก ฉันคิดว่ามันเกี่ยวกับความเร็วในการจัดสรร
Stas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.