VS 2013 , console, x64 bit project.
OpenSSL Version: 1.0.2h x64
Method for obtaining SHA1 hash:
#include <openssl/sha.h> void SHA1::ComputeHash(std::vector<unsigned char> &buffer, std::vector<unsigned char> &result) { int i = 0; SHA_CTX sha1handler; unsigned char sha1digest[SHA_DIGEST_LENGTH] = { 0 }; auto str = std::string(buffer.begin(), buffer.end()); SHA1_Init(&sha1handler); SHA1_Update(&sha1handler, &str, str.size()); SHA1_Final(sha1digest, &sha1handler); Framework::Array::Copy(sha1digest, 0, result, 0, SHA_DIGEST_LENGTH); } Framework::Array::Copy method:
void Array::Copy(unsigned char *sourceArray, int sourceIndex, std::vector<unsigned char> &destinationArray, int destinationIndex, int length) { if (destinationArray.size() == 0 || destinationArray.size() < (destinationIndex + length)) destinationArray.resize(destinationIndex + length); for (int i = sourceIndex; i < (sourceIndex + length); i++) { destinationArray[destinationIndex] = sourceArray[i]; destinationIndex++; } } Framework::Array::AddRange :
void Array::AddRange(std::vector<unsigned char> &sourceArray, std::vector<unsigned char> &destinationArray, int offset, int length) { for (int i = offset; i < (offset + length); i++) destinationArray.push_back(sourceArray[i]); } A method in which a pointer or garbage is returned from memory instead of a value:
void Hash(std::vector<unsigned char> &inData, std::vector<unsigned char> &salt1, std::vector<unsigned char> &salt2, int salt) { std::vector<unsigned char> buffer(20); std::vector<unsigned char> buffer2(4); std::vector<unsigned char> destinationArray(0x30); int num = 0; for (num = 0; num < 3; num++) { for (int i = 0; i <= num; i++) buffer2[i] = (salt + num); std::vector<unsigned char> localBuffer; Framework::Array::AddRange(buffer2, localBuffer, 0, (num + 1)); Framework::Array::AddRange(inData, localBuffer, 0, 0x30); Framework::Array::AddRange(salt1, localBuffer, 0, 0x20); Framework::Array::AddRange(salt2, localBuffer, 0, 0x20); SHA1::ComputeHash(localBuffer, buffer); // Вот тут в buffer возвращается указатель или мусор из памяти! } } The question is - why does the pointer / garbage return? If you need any more data - write in the comments. It’s not the first time that I’ve encountered something like this, the last time I failed to reproduce the problem, I hope at least this time the reason will become clear.
Update:
It was possible to find out that the pointer \ garbage is returned from OpenSSL, an example of changing the value:
1) http://i7.5cm.ru/i/kkXu.png
2) http://i7.5cm.ru/i/caXS.png
Method:
void SHA1::ComputeHash(std::vector<unsigned char> &buffer, std::vector<unsigned char> &result) { int i = 0; SHA_CTX sha1handler; unsigned char sha1digest[SHA_DIGEST_LENGTH] = { 0 }; // Выводим HEX значение буфера printf("Buffer HEX: "); for (int i = 0; i < (int)buffer.size(); i++) printf("%X-", buffer[i]); printf("\r\n\r\n"); std::string str = std::string(buffer.begin(), buffer.end()); // Выводим длину строки printf("Str Length: %u\r\n\r\n", str.size()); // Выводим HEX значение строки printf("Str HEX: "); for (int i = 0; i < str.size(); i++) printf("%X-", str[i]); printf("\r\n\r\n"); if (!SHA1_Init(&sha1handler)) { printf("SHA1_Init == false\r\n"); // Все ок, сообщение не выводится } if (!SHA1_Update(&sha1handler, &str, str.size())) { printf("SHA1_Update == false\r\n"); // Все ок, сообщение не выводится } if (!SHA1_Final(sha1digest, &sha1handler)) { printf("SHA1_Final == false\r\n"); // Все ок, сообщение не выводится } // Выводим HEX значение результата обработки SHA1 printf("SHA1 result HEX: "); for (int i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%X-", sha1digest[i]); printf("\r\n\r\n"); Framework::Array::Copy(sha1digest, 0, result, 0, SHA_DIGEST_LENGTH); } ps tried the older version of OpenSSL (v1.0.1t x64) - the problem is also preserved.
Test project: https://www.sendspace.com/file/japr5z
OpenSSL for Windows: https://slproweb.com/products/Win32OpenSSL.html