SHA256 Hash FString

I simply want to SHA256 an FString to send to my server. I spent the last month creating an account server that authenticates using SHA256 strings after hearing about the flaws with SHA1. I have no problems generating SHA1 with UE4 but it seems that the 256 version is implemented differently?

Everything compiles fine but crashes during runtime

Here is the function:

FString UHashFunctionLibrary::SHA256_ENCODE(const FString& inString) {
	uint32 size = inString.Len();
	
	TArray<uint8> sData;
	sData.AddUninitialized(size);
	StringToBytes(inString, sData.GetData(), size);
	
	FSHA256Signature retSig;
	FGenericPlatformMisc::GetSHA256Signature(sData.GetData(), size, retSig);
	return retSig.ToString();
}

And the crash reports:
Assertion failed: false [File:D:\Build++UE4+Release-
4.18+Compile\Sync\Engine\Source\Runtime\Core\Private\GenericPlatform\GenericPlatformMisc.cpp] [Line: 899] No SHA256 Platform implementation

The problem line:

FGenericPlatformMisc::GetSHA256Signature(sData.GetData(), size, retSig);

I haven’t seen any questions asked on the forum or hub about this. I see there is a plugin or two available but I would strongly prefer not to use them. I am developing a multi-platform game and would like to use unreal’s built-in hashing functions that are cross-platform compatible. I know UE4 uses SHA256 internally and there is clearly some implementation. I just don’t really know what to make of that error.

Thank you so much in advance! This is a serious roadblock for me and while I could switch everything to SHA1 authentication, that would be taking a step back security-wise.

1 Like

Use FPlatfromMisc instead of FGenericPlatformMisc. “Generic” is fall back implementation, some of them simply crashes if something is not implemented in specific platform implementation and you hit one of such examples

What UE4 platform API work is that each platform have it own of set classes, so for example Windows have prefix FWindowsPlatform* and Android for example will have FAndroidPlatform* and during compilation the specific ser for platform that compilation happens for gets typename-ed to FPlatform, so always use FPlatform. Because this is kind of a C++ hack API reference only shows Generic platform implementation which is fallback implementation that all platform implementation inherent form and if there missing function it falls back to Generic. Some platform implementations also have some extra exclusive functions, this is only case where you not use FPlatfrom and reference platform implementation directly

So I took a look at the source of GetSHA256Signature() and it looks like its not implemented? The first checkf is hardcoded with false?

bool FGenericPlatformMisc::GetSHA256Signature(const void* Data, uint32 ByteSize, FSHA256Signature& OutSignature)
{
	checkf(false, TEXT("No SHA256 Platform implementation"));
	FMemory::Memzero(OutSignature.Signature);
	return false;
}

Can UE4 create a SHA256 hash without a third party library?

Thanks for the reply! Unfortunately changing “FGenericPlatformMisc” to “FPlatformMisc” still produces the same error. It seems to be calling the generic one anyways :frowning:

Assertion failed: false [File:D:\Build\++UE4+Release-4.18+Compile\Sync\Engine\Source\Runtime\Core\Private\GenericPlatform\GenericPlatformMisc.cpp] [Line: 899] No SHA256 Platform implementation

You right there no implmentation on any platfrom and this function in engine is only used by HTTP module. I can only find MD5 and SHA1 implmentations in engine:

https://github.com/EpicGames/UnrealEngine/blob/8e4560b8c22b309e73ff0ce90377742c3dfe13cc/Engine/Source/Runtime/Core/Public/Misc/SecureHash.h

Hmmm you could try calling OpenSSL direcly for SHA256 hash, OpenSSL is included in UE4, you just need to ThirdParty depency in your module build script, here example:

https://github.com/EpicGames/UnrealEngine/blob/8e4560b8c22b309e73ff0ce90377742c3dfe13cc/Engine/Plugins/Developer/PerforceSourceControl/Source/PerforceSourceControl/PerforceSourceControl.Build.cs

Got it working
 prehaps its not best solution but its working for me.

I using the sha256.h and sha256.cpp file from zedwood function. found here
http://www.zedwood.com/article/cpp-sha256-function

Jah need to insert the #define _CRT_SECURE_NO_WARNINGS in the sha256.cpp

Because the function expects std.string and not fstring 
 jah need to convert them like this
FString hash_user_name = *FString(sha256(TCHAR_TO_UTF8(*User_Name)).c_str());

Then jah can get the code working and jah got a nice sha256 hash signature.

Sorry I am new to CPP, may I know how can you include the OpenSSL and example usage of it? Thank you!

I do not know if anyone else is looking for a solution to the problem or maybe just someone will need the ability to transfer Fstring to SHA256. Then here is an example of the code that I found and adapted for UE5. You can call the Get_Hash function in the BluДprint.

Block.h

include “CoreMinimal.h”
include “GameFramework/Actor.h”
include “C_Block.generated.h”

UCLASS()
class BLOCKCHAINE_API AC_Block : public AActor
{
GENERATED_BODY()

// Functions

public:
// Sets default values for this actor’s properties
AC_Block();

UFUNCTION(BlueprintCallable)
FString Get_Hash(FString Get_Word);

protected:

// Called when the game starts or when spawned
virtual void BeginPlay() override;

private:

std::string Calculate_Hash(const std::string str) const;

public:

// Called every frame
virtual void Tick(float DeltaTime) override;
};

And

Block.cpp

include “C_Block.h”

include <iomanip
include <sstream
include <openssl/sha.h>

// Sets default values
AC_Block::AC_Block()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;

}

FString AC_Block::Get_Hash(FString Get_Word)
{

std::string TestString = Calculate_Hash(std::string(TCHAR_TO_UTF8(*Get_Word)));
FString HappyString(TestString.c_str());
return HappyString;
}

// Called when the game starts or when spawned
void AC_Block::BeginPlay()
{
Super::BeginPlay();

}

std::string AC_Block::Calculate_Hash(const std::string str) const
{
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(), str.size());
SHA256_Final(hash, &sha256);

std::stringstream ss;

for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << std::setw(2) << std::setfill(‘0’) << static_cast(hash[i]);
}

return ss.str();
}

// Called every frame
void AC_Block::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);

}

Too

YourProject.Build.cs

using UnrealBuildTool;

public class Blockchain : ModuleRules
{
public Blockchain(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

  PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "OpenSSL" });

  PrivateDependencyModuleNames.AddRange(new string[] { "OpenSSL" });

  AddEngineThirdPartyPrivateStaticDependencies(Target, "OpenSSL");

}
}