erotavlas
erotavlas

Reputation: 4483

How to - SHA1 hash of plaintext using SHA1CryptoServiceProvider in C++/CLI?

I want to hash a string but looking at the example on MSDN I got stuck on the DATA_SIZE. What is this? and how do I know ahead of time what the size of the array is if the plaintext can vary in length?

Also I need to return the result as a vector (consuming method expects this)

Code from MSDN

array<Byte>^ data = gcnew array<Byte>( DATA_SIZE );
array<Byte>^ result;

SHA1^ sha = gcnew SHA1CryptoServiceProvider;
// This is one implementation of the abstract class SHA1.
result = sha->ComputeHash( data );

My method so far looks like

std::vector<byte> sha1(const std::string& plaintext)
{
    //#define SHA1_BUFFER_SIZE  ????
    //array<System::Byte>^ data = gcnew array<System::Byte>(DATA_SIZE);

    //convert plaintext string to byte array

    array<System::Byte>^ result;
    SHA1^ sha = gcnew SHA1CryptoServiceProvider;
    result = sha->ComputeHash(data);

    //return result as a vector<byte>
}

Upvotes: 0

Views: 807

Answers (1)

Lelo
Lelo

Reputation: 912

First, answering your questions:

  • On the referred MSDN page, it was stated before the example:

This example assumes that there is a predefined constant DATA_SIZE.

So, it was assumed that there was a #define or a enum constant predefined

  • Of course you don't know the size of the plaintext. But you'll see that in this approach you don't need the DATA_SIZE constant

If you want your function to receive as input a std:string and to output a std::vector, there are a lot of steps to be done. It would look something like that:

std::vector<unsigned char> sha1(const std::string& message)
{
    // Steps #1 and #2: convert from std::string to managed string
    //                  and convert from a string to bytes (UTF-8 as example)
    array<Byte>^data =  Encoding::UTF8->GetBytes(gcnew String(message.c_str() ));


    // Steps #3 and #4: perform hash operation
    //                  and store result in a byte array
    SHA1^ sha = gcnew SHA1CryptoServiceProvider;
    array<Byte>^ array_result = sha->ComputeHash(data);

    // Step #5: convert from a managed array
    //          to unmanaged vector
    std::vector<unsigned char> vector_return(array_result->Length);
    Marshal::Copy(array_result, 0, IntPtr(&vector_return[0]), array_result->Length);

    return vector_return;
}

don't forget to declare the namespaces you're using:

using namespace System;
using namespace System::Text;
using namespace System::Security::Cryptography;
using namespace System::Runtime::InteropServices;

int main(array<System::String ^> ^args)
{
    std::string str_test("This is just a test.");
    std::vector<unsigned char> vec_digest( sha1(str_test) );

    return 0;
}

Final thoughts:

  • It's a bit misleading to name the string you want to hash as plaintext. More accurate terms would be message (for the input data) and digest (for the hash value)
  • Avoid mixing the use of std::string and managed String^ if you can.

Upvotes: 1

Related Questions