UE4 AES加密解密(解决中文乱码问题)

UE4自带了AES的加密解密方法,但是找了一下并没有加密解密成功的文章,于是写下这篇给大家,第一次写博客,写不好,写错的地方请帮忙指出。

参考文章:

1.https://blog.csdn.net/szu_it_man/article/details/78790408   @某校不良生,文章简介指出“原文本和解密后的文本不一致”的问题,我再使用的时候也出现了这个问题,后来同事(膜拜大佬同事)发现告知解密的的文本乱码也是有规律的,规律为:“原文+乱码”,所以只需要取出其中正确的原文即可。取出的方法是手动给原文加上分隔符后再加密。解密后的字符串使用分隔符分割获取左侧的字符串即可。

2.https://blog.csdn.net/cartzhang/article/details/79505695   @cartzhang,根据文章的代码再加上面所说分割字符串,就可以实现使用ue4自带的AES加密解密了,但是这个时候问题又出现了,输入中文的话,输出的结果是乱码的。。。我的解决方法是先把FString转成TArray,再转成Base64后加密。同理,解密后的是Base64,先转成TArray,再转成FString。方法有点蠢但是又用,如果又更好更简单的方法请留言,谢谢!

实现步骤目录:

1.转换格式到Base64(中文乱码问题处理)

2.添加分割符

3.加密(包括加密和生成密钥)

4.解密

5.转回到原来的FString

具体实现如下:

.h

public:
	UFUNCTION(BlueprintCallable, Category = "AES")
		static UMyObject * GetAESInstance();
	UFUNCTION(BlueprintCallable, Category = "AES")
		void EncryptDataTest(FString RawData, FString& Aes, FString &Keys);
	UFUNCTION(BlueprintCallable, Category = "AES")
		void DecryptDataTest(FString Aes, FString Keys, FString& RawData);
private:
	//分隔符,为了不和用户冲突所以写的乱七八糟的,也可以写其他的,比如“abcd”
	FString SplitSymbol = "¥……¥%#&*¥&…%";

	static UMyObject* AESInstance;

.cpp

#include "string"
#include "Base64.h"
#include "Misc/AES.h"

UMyObject *UMyObject::AESInstance = nullptr;
UMyObject * UMyObject::GetAESInstance()
{
	if (AESInstance == nullptr)
	{
		AESInstance = NewObject();
		AESInstance->AddToRoot();
	}
	return AESInstance;
}

void UMyObject::EncryptDataTest(FString RawData, FString& Aes, FString &Keys)
{

	//1.转换格式到Base64//先转成TArray,再转成FBase64
	TArray content;
	std::string _s(TCHAR_TO_UTF8(*RawData));
	content.Append((unsigned char *)_s.data(), _s.size());
	FString centerString =FBase64::Encode(content);

	//2.添加分割符
	centerString.Append(SplitSymbol);

	//3.生成密钥
	//注意:这里需要记录一下原文的长度,为了从base64转回TArray给予适合的长度(可多不可少),原理我也不知道/(ㄒoㄒ)/~~
	//考虑到其中有中文,为了安全直接乘以4,然后“;”用来分隔
	//其实不用放在密钥里面也是可以的,作为一个单独的参数传出去,密钥另外生成
	//密钥长度需要为32位
	Keys = FString::FromInt(RawData.Len() * 4) + ";";
	for (int i = Keys.Len(); i < 32; i++)
	{
		Keys.Append("a");
	}
	TCHAR *KeyChars = Keys.GetCharArray().GetData();

	//4.生成密钥
	uint8* Blob = nullptr;
	uint32 SizeU;
	SizeU = centerString.Len();
	//这里的意思为把SizeU长度向上取整的16的倍数,比如长度为5.那么SizeU为16,长度为20,那么SizeU为32,以此类推
	SizeU = SizeU + (FAES::AESBlockSize - (SizeU % FAES::AESBlockSize));
	Blob = new uint8[SizeU];
	StringToBytes(centerString, Blob, SizeU);
	FAES::EncryptData(Blob, SizeU, TCHAR_TO_ANSI(KeyChars));
	Aes = FString::FromHexBlob(Blob, SizeU);//这个就是我们要的密文了
}

void UMyObject::DecryptDataTest(FString Aes, FString Keys, FString& RawData)
{
	//1.解密得到原先加密的"Base64+乱码"
	uint8* Blob;
	int32 SizeU;
	SizeU = Aes.Len();
	SizeU = SizeU - (FAES::AESBlockSize - (SizeU % FAES::AESBlockSize));
	Blob = new uint8[SizeU];
	FString::ToHexBlob(Aes, Blob, SizeU);
	TCHAR *KeyChars = Keys.GetCharArray().GetData();
	FAES::DecryptData(Blob, SizeU, TCHAR_TO_ANSI(KeyChars));
	FString centerBase64 = BytesToString(Blob, SizeU);

	//2.使用分隔符从Base64和乱码中取回base64
	FString LeftData;
	FString RightData;
	centerBase64.Split(SplitSymbol, &LeftData, &RightData, ESearchCase::CaseSensitive, ESearchDir::FromStart);
	centerBase64 = LeftData;

	//3.从base64转回TArray
	TArray content;
	FBase64::Decode(centerBase64, content);
	Keys.Split(";", &LeftData, &RightData, ESearchCase::CaseSensitive, ESearchDir::FromStart);

	//4.给TArray设置适合的长度——这里原理我不懂,为啥Base64转回来还要设置这个(测试过不设会乱码)
	content.SetNum(FCString::Atoi(*LeftData));
	content[FCString::Atoi(*LeftData) - 1] = 0;

	//5.再转回来就可以了
	RawData= FString(UTF8_TO_TCHAR(content.GetData()));
}

为了大家方便看我就全部写在一起了,大家自己写的话该封装封装~~~

蓝图:UE4 AES加密解密(解决中文乱码问题)_第1张图片

输出效果:



本篇完结,如果有同志指教,我也会更新出来,谢谢~

你可能感兴趣的:(UE4)