How to convert SecByteBlock to string?

后端 未结 2 2071
耶瑟儿~
耶瑟儿~ 2020-12-06 22:27

I\'m having a problem trying to convert SecByteBlock to string. Here\'s my case:

I want to encrypt user access data using AES with static key and dynami

相关标签:
2条回答
  • 2020-12-06 22:41

    I'm having a problem trying to convert SecByteBlock to string

    If the issue is with conversion from SecByteBlock and its byte array to a std::string and its char array, then you should:

    SecByteBlock iv;
    ...
    
    // C-style cast
    std::string token = std::string((const char*)iv.data(), iv.size()) + userAccess;
    

    Or,

    SecByteBlock iv;
    ...
    
    // C++-style cast
    std::string token = std::string(reinterpret_cast<const char*>(iv.data()), iv.size()) + userAccess;
    

    You can also forgo the assignment, and just initialize and later append:

    SecByteBlock iv;
    ...
    
    std::string token(reinterpret_cast<const char*>(iv.data()), iv.size());
    ...
    
    std::string userAccess;
    ...
    
    token += userAccess;
    

    The other problem you might have is string to SecByteBlock. You should do this:

    std::string str;
    ...
    
    // C-style cast
    SecByteBlock sbb((const byte*)str.data(), str.size());
    

    Or:

    std::string str;
    ...
    
    // C++-style cast
    SecByteBlock sbb(reinterpret_cast<const byte*>(str.data()), str.size());
    
    0 讨论(0)
  • 2020-12-06 22:46

    I think Eric answered your primary question on how to convert the SecByteBlock to a std::string (including the explicit conversions between char* and byte*). But here's how you might approach std::string token = std::string(iv.begin(), iv.end()) + userAccess; issue.

    string token;
    
    SecByteBlock iv(16), userAccess(16);
    OS_GenerateRandomBlock(false, iv, iv.size());
    OS_GenerateRandomBlock(false, userAccess, userAccess.size());
    
    SecByteBlock nil;
    nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH);
    
    HMAC<SHA256> hmac;
    hmac.SetKey(nil.data(), nil.size());
    
    HashFilter filter(hmac, new HexEncoder(new StringSink(token)));
    filter.Put(iv.data(), iv.size());
    filter.Put(userAccess.data(), userAccess.size());
    filter.MessageEnd();
    
    cout << token << endl;
    

    The SecByteBlock nil creates an object with no memory or size. The nil.CleanNew(HMAC<SHA256>::DEFAULT_KEYLENGTH) sizes and initializes the SecByteBlock to 0. Otherwise, you have an uninitialized block of memory.

    It is possible to declare it and size it with a 0-inialized array, but you have to be familiar with the sources because its no Doxygen-docimented as of Crypto++ 5.6.2. That way is to use a NULL pointer, but a non-0 size. Here's what it would look like, but its very non-intuitive:

    SecByteBlock nil(NULL, HMAC<SHA256>::DEFAULT_KEYLENGTH);
    

    The trick relies on this SecBlock<T> constructor:

    00250    SecBlock(const T *t, size_type len)
    00251        : m_size(len)
    00252    {
    00253        m_ptr = m_alloc.allocate(len, NULL);
    00254        if (t == NULL)
    00255            memset_z(m_ptr, 0, len*sizeof(T));
    00256        else
    00257            memcpy(m_ptr, t, len*sizeof(T));
    00258    }
    

    If possible, you should use HKDF instead of the HMAC<SHA> with a nil vector to extract the entropy from the security parameters. You can find the HKDF in the repo at the HKDF class. Its a stand alone header, so it will "just work".


    A typical run of the program with random values for iv and userAccess is:

    $ ./cryptopp-test.exe
    061CF705259058C4E01A2BF22830FC3F2A7E97F12FE605B38405B1E1B19A9E0F
    

    Another way to approach it could be concatenation based on SecByteBlock's operator +=. The result is a binary string, and not a human readable ASCII string.

    SecByteBlock result;
    
    result += iv;
    result += SecByteBlock(userAccess.data(), userAccess.size());
    
    string token(result.data(), result.size());
    

    If you need a human readable string, then run it through a HexEncoder:

    HexEncoder hex(new StringSink(token));
    hex.Put(result.data(), result.size());
    hex.MessageEnd();
    

    But it does not extract the entropy from the parameters, so I personally like it less.


    When you move from a SecByteBlock to a std::string, you effectively lose your secure allocator. That means the data in the copies will not be zeroized after egressing data to the string object.


    The HexEncoder is a convenience item, and it allows you to dump the binary string.

    Another useful one might be the Base64URLEncoder. It uses the web safe alphabet.

    0 讨论(0)
提交回复
热议问题