안전한 암호화 키를 위해 std :: array에 사용자 지정 할당자를 사용할 수 있습니까?


9

std::array스택에 완전히 할당 된 것을 알고 있지만이 질문은 두 가지 사항이 필요한 보안 문제로 인해 발생합니다.

  1. std::array파괴시 데이터는 제로화되거나 무작위 화됩니다.
  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.

더 나은 해결책이 있습니까?


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Samuel Liew

죄송합니다. 다른 하나는 깃발이 아니라 당신을 거부하는 모드였습니다. 당신이 할 수있는 유일한 것은 물론 대답이 올바른지 아닌지를 나타내는 것입니다. 그래서 현상금을 가장 좋은 것으로 지정할 수 있습니다. 나는 물론 나 자신을 평가할 수 있지만, 나는 위대한 전문가가 아닙니다. 현상금에 대한 이유는 일단 할당되면 사라집니다.
Maarten Bodewes

@ Maarten-reinstateMonica 불행히도 어떤 대답도 깨끗한 방법으로 문제를 해결하지 못합니다.
Quantum Physicist

@TheQuantumPhysicist 깨끗한 방법으로 여겨지기 위해서는 무엇이 필요할까요? 이러한 요구 사항을 명시 적으로 시도해 볼 수 있습니까? 그것은 가능한 해결책에 대해 생각하는 데 도움이됩니다. 나는 당신이 무엇을 의미하는지 알 것 같지만, 아마도 더 정확할 수 있다고 생각합니다.
Maarten Bodewes 2014

@ Maarten-reinstateMonica 이미 어떤 식 으로든 할당자를 사용합니다. 처음부터 물건을 다시 쓰는 것은 좋지 않은 생각이며 테스트가 필요합니다. 이것이 최후의 수단이되어야합니다. 아래의 답변은 이미 언급 한 명백한 해결책을 제안합니다 (채팅으로 옮기기 전에).
양자 물리학 자

답변:


5

std::array할당자를 사용할 수 없습니다. 그러나 SecureArray 클래스가 사용자 정의 생성자 / 해체자를 통해 원하는 것을 얻을 수있는 것처럼 보입니다.

이 같은:

#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.