Score:0

Generate SHA256 Hash of a STRING from Windows Command Line

ca flag

While this is simple to do in the *nix world, I can't come up with a solution for generating a SHA256 hash of a string from the Windows command shell (not PowerShell) without installing a 3rd party application or batch file.

CertUtil works fine for generating a hash of a file, but I want the hash of a plain string so that it can be copy/pasted to be used elsewhere by some developers.

I'm looking for something in Windows that would work like this does on a Mac:

echo -n "foobar" | shasum -a 256

That generates a hash of "c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2".

Any help would be appreciated. I'm a Mac guy, and I'm just trying to put together some docs for our developers - and some of them use Windows.

Score:3
jp flag

Windows batch/cmd script

The certutil does not support input from a pipe, but only

certutil [options] -hashfile infile [hashalgorithm] 

Therefore, a temporary file is required.

This Windows cmd script takes a string as its arguments and returns the SHA-256 hash.

@echo off
if [%1]==[] goto usage

set STRING="%*"
set TMPFILE="%TMP%\hash-%RANDOM%.tmp"
echo | set /p=%STRING% > %TMPFILE%
certutil -hashfile %TMPFILE% SHA256 | findstr /v "hash"
del %TMPFILE%
goto :eof

:usage
echo Usage: %0 string to be hashed

An example, where this script is named sha256sum.cmd:

C:\>sha256sum.cmd
Usage: sha256sum.cmd string to be hashed

C:\>sha256sum.cmd foobar
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2

C:\>sha256sum.cmd foo bar
fbc1a9f858ea9e177916964bd88c3d37b91a1e84412765e29950777f265c4b75

These are the same hashes as with sha256sum:

$ echo -n "foobar" | sha256sum
c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2  -
$ echo -n "foo bar" | sha256sum
fbc1a9f858ea9e177916964bd88c3d37b91a1e84412765e29950777f265c4b75  -

PowerShell

The Get-FileHash cmdlet supports input streams that can replace the temporary files.

Based on the example 4 it is possible to recreate the preceding cmd script in PowerShell:

if($args.Count -eq 0) {
  Write-Host "Usage: .\$($MyInvocation.MyCommand.Name) string to be hashed";
  exit 1
}

$stringAsStream = [System.IO.MemoryStream]::new()
$writer = [System.IO.StreamWriter]::new($stringAsStream)
$writer.write("$args")
$writer.Flush()
$stringAsStream.Position = 0
Get-FileHash -Algorithm SHA256 -InputStream $stringAsStream `
  | Select-Object Hash `
  | ForEach-Object {$_.Hash}

An example, where this script is named sha256sum.ps1:

PS C:\> .\sha256sum.ps1
Usage: .\sha256sum.ps1 string to be hashed

PS C:\> .\sha256sum.ps1 foobar
C3AB8FF13720E8AD9047DD39466B3C8974E592C2FA383D4A3960714CAEF0C4F2

PS C:\> .\sha256sum.ps1 foo bar
FBC1A9F858EA9E177916964BD88C3D37B91A1E84412765E29950777F265C4B75
Michael Oryl avatar
ca flag
Thanks very much. I'm sure many will find this helpful. Unfortunately, I was looking for a solution that would allow a Windows user to generate the code without needing to install software or use batch files that are not already on their system. I'm guessing that's simply not possible. Thanks very much, though.
in flag
You can wrap it in a single line. `echo "foobar" > %TMP%/hash.txt |certutil -hashfile %TMP%/hash.txt SHA256 | findstr /v "hash"`
jp flag
@GeraldSchneider That has a different hash as it contains an extra newline.
Score:1
cd flag

OP requested a one-liner that doesn't require "running" a batch file, so here's said one-liner, derived from @GeraldSchneider's comment and this answer:

echo|set /p="foobar" > %TMP%/hash.txt |certutil -hashfile %TMP%/hash.txt SHA256 | findstr /v "hash"
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.