Generating a Sha-256 Hash from the Linux Command Line

Generating a SHA-256 hash from the Linux command line

echo will normally output a newline, which is suppressed with -n. Try this:

echo -n foobar | sha256sum

Generating just a SHA-256 hash from the Linux command line

You may use:

sh -c 'shasum < "$1" | cut -d" " -f1' -- "$file"

Linux command line SHA-256 hash different from online tools?

I ran into this problem while doing something similar.

What I was doing was something like echo string | sha256sum, I think.

I'd get a different result when I ran this through the php hash generator. The reason was because of the new line that echo added.

I don't know if you're using echo but if you are try echo -n string | sha256num.

How to generate sha256 hashes of hexadecimal binary data in c++?

First you should know that your command-line version is missing a nibble. I.e., if you send '616161616161616'` through xxd -r -p, then back through xxd, you'll see this:

echo -n "616161616161616" | xxd -r -p | xxd
00000000: 6161 6161 6161 61 aaaaaaa

Note the last nibble 6 is missing. The xxd utility consumes hex in pairs of digits. Once there are no more pairs it stops and emits the final output. Chances are you were expecting behavior that treated the leading nibble as a single octet, and therefore something like this:

echo -n "0616161616161616" | xxd -r -p | xxd
00000000: 0616 1616 1616 1616 ........

In either case, and however you want to handle that, you should nonetheless be made aware of the issue.

Regarding your actual problem, the OpenSSL library has a fairly rich set of features that let you do most of what you're asking near-trivially. Calculating the digest from the input string is fairly simple:

#include <iostream>
#include <vector>
#include <string>

#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

int main()
{
std::string strHex = "616161616161616"; // get this from wherever

// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.insert(strHex.begin(), '0');

// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);

// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);

// free the input data.
OPENSSL_free(bin);

// print the buffer to stdout in hex.
char *hexOut = OPENSSL_buf2hexstr(md.data(), md_len);
std::cout << hexOut << '\n';
OPENSSL_free(hexOut);

return 0;
}

Note the above code takes the approach of prepending a zero-nibble in the case of an odd input length. If that isn't the behavior you want (i.e. if you want the exact same ignore-the-trailing-odd-nibble behavior as your question text), the alternative is to trim the last nibble off (which I seriously doubt is what you want is it removes relevant bits and is a recipe for digest collisions, but your call).

#include <iostream>
#include <vector>
#include <string>

#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

int main()
{
std::string strHex = "616161616161616"; // get this from wherever

// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.pop_back();

// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);

// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);

// free the input data.
OPENSSL_free(bin);

// print the buffer to stdout in hex.
char *hexOut = OPENSSL_buf2hexstr(md.data(), md_len);
std::cout << hexOut << '\n';
OPENSSL_free(hexOut);

return 0;
}

In both cases above, the resulting output is preconfigured as colon-separated octets. I.e. the latter example output looks like this:

E4:62:40:71:4B:5D:B3:A2:3E:EE:60:47:9A:62:3E:FB:A4:D6:33:D2:7F:E4:F0:3C:90:4B:9E:21:9A:7F:BE:60

This is due to the rather-limited feature capability of OPENSSL_buf2hexstr. If this isn't what you want (probably isn't), you could always manually print it yourself using a simple lookup table, processing each octet as two nibbles:

#include <iostream>
#include <vector>
#include <string>

#include <openssl/evp.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

int main()
{
std::string strHex = "616161616161616";

// prepend zero-nibble for odd character counts.
if (strHex.length() % 2)
strHex.pop_back();

// convert to blob. returns dynamic memory allocated with
// OPENSSL_malloc. Use OPENSSL_free to destroy it.
long len = 0;
unsigned char *bin = OPENSSL_hexstr2buf(strHex.c_str(), &len);

// digest the blob
const EVP_MD *md_algo = EVP_sha256();
unsigned int md_len = EVP_MD_size(md_algo);
std::vector<unsigned char> md( md_len );
EVP_Digest(bin, len, md.data(), &md_len, md_algo, nullptr);

// free the input data.
OPENSSL_free(bin);

// dump as continuous hex string
static const char alpha[] = "0123456789abcdef";
for (auto c : md)
{
std::cout << alpha[ (c >> 4) & 0xF];
std::cout << alpha[ c & 0xF];
}
std::cout.put('\n');

return 0;
}

Output

e46240714b5db3a23eee60479a623efba4d633d27fe4f03c904b9e219a7fbe60

Anyway, longer than I intended, but hope it was what you were looking for.

OpenSSL create SHA hash from shell stdin

Try echo -n "password".

What's happening is the new line character(s) that echo adds to the end of the string are getting hashed. The -n to echo suppresses this behavior.



Related Topics



Leave a reply



Submit