欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UE4 Crypto++库调用 AES加密

程序员文章站 2022-06-10 23:27:25
...

UE4 Crypto++库调用 AES加密

原因
  • 还是官方的AES 不行,加解密有问题
参考文章:
  • 1.https://blog.csdn.net/liang19890820/article/details/51659452
  • 2.https://blog.csdn.net/Szu_IT_Man/article/details/78790408
    ---- 俩篇文章能够实现加解密,但是对于长文本加解密,在UE4上出现问题,一直找不到原因,就放弃直接去看官方demo了
官方demo
  • http://www.cryptopp.com/wiki/Advanced_Encryption_Standard#Downloads

这里我们跳过编译的过程,直接看代码,编译过程看参考文章 1 就行

以AES ECB demo为例(只看main函数)
int main(int argc, char* argv[])
{
	AutoSeededRandomPool prng;

	byte key[AES::DEFAULT_KEYLENGTH];
	//通过内部的random方法 随机出一个key
	prng.GenerateBlock(key, sizeof(key));

	string plain = "ECB Mode Test";
	string cipher, encoded, recovered;

	encoded.clear();
	//注意 这个stringsource只是获取key的值用,打印用而已,后面加密实际用的还是byte型的key,所以我们到时候在将key传进来的时候也需要转换成 byte类型的
	StringSource(key, sizeof(key), true,new HexEncoder(new StringSink(encoded)) ); 
	cout << "key: " << encoded << endl;
	
	try
	{
		cout << "plain text: " << plain << endl;
		//定义一个ECB模式 Encryption对象
		ECB_Mode< AES >::Encryption e;
		//Encryption中传入key
		e.SetKey(key, sizeof(key));
		//这个StringSource才是真正的加密过程,cipher就是加密后的密文,plain是明文,此时的cipher还是不可读的,在后面stringSource转换成 可读 string后才可读
		StringSource(plain, true, new StreamTransformationFilter(e,new StringSink(cipher)));
	}
	catch(const CryptoPP::Exception& e)
	{
		cerr << e.what() << endl;
		exit(1);
	}
	
	encoded.clear();
	//转换密文cipher可读,打印encode
	StringSource(cipher, true,new HexEncoder(new StringSink(encoded)) ); 
	cout << "cipher text: " << encoded << endl;

	try
	{
	    //解密定义ECB模式的Decryption 
		ECB_Mode< AES >::Decryption d;
		//设置解密用的密码 key
		d.SetKey(key, sizeof(key));
		//注意观察,这里解密StringSource用的是不可阅读的密文cipher,到时候我们用的时候需要先将可读的密文string反转一下
		StringSource s(cipher,true, new StreamTransformationFilter(d,new StringSink(recovered))); 
		cout << "recovered text: " << recovered << endl;
	}
	catch(const CryptoPP::Exception& e)
	{
		cerr << e.what() << endl;
		exit(1);
	}

	return 0;
}
将这段代码的加密解密分开后就是下面的代码

static std::string KeyStr = "0123456789ABCDEF0123456789ABCDEF";
static std::string IVStr = "ABCDEF0123456789";
//将stirng型的key转成byte供库使用
SecByteBlock GetKey()
{
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	KeyStr.size() <= AES::MAX_KEYLENGTH
		? memcpy(key, KeyStr.c_str(), KeyStr.size())
		: memcpy(key, KeyStr.c_str(), AES::MAX_KEYLENGTH);
	return key;
}
//将stirng型的IV转成byte供库使用
SecByteBlock GetIV()
{
	SecByteBlock IV(AES::BLOCKSIZE);
	memset(IV, 0x30, IV.size());
	KeyStr.size() <= AES::BLOCKSIZE
        ? memcpy(IV, IVStr.c_str(), IVStr.size())
        : memcpy(IV, IVStr.c_str(), AES::BLOCKSIZE);
	return IV;
}
#pragma region ECB
FString ECB_EnCrypto(string inPlain)
{
	string cipher; //存密文
	string cipherOut; //存输出的string密文
	SecByteBlock Key = GetKey();
	ECB_Mode<AES>::Encryption e;
	e.SetKey((byte*)Key, AES::MAX_KEYLENGTH);
	//这一步StingSource是将明文通过 encryption进行加密,得到cipher密文
	StringSource(inPlain, true,
	             new StreamTransformationFilter(e,
	                                            new StringSink(cipher)
	                                            , BlockPaddingSchemeDef::ONE_AND_ZEROS_PADDING
	                                            , true
	             )
	);
	//这一步是通过StringSource 将cipher 密文转成可以正常打印阅读的 密文,主要关注HexEncoder 
	StringSource(cipher, true,
	             new HexEncoder(
		             new StringSink(cipherOut)
	             )
	);
	UE_LOG(LogTemp, Warning, TEXT(" the cipher:%s"), UTF8_TO_TCHAR( cipherOut.c_str()));
	return UTF8_TO_TCHAR(cipherOut.c_str());
}

FString ECB_DeCrypto(string inCipher)
{
	string plain; //存明文
	string plainOut; //存输出的string明文
	//既然加密后有对密文Encoder,那我们也一样要对密文先进行Decoder
	StringSource(inCipher, true,
	             new HexDecoder(new StringSink(plain)
	             )
	);
	ECB_Mode<AES>::Decryption d;
	SecByteBlock Key = GetKey();
	d.SetKey((byte*)Key, AES::MAX_KEYLENGTH);
	StringSource s(plain, true,
	               new StreamTransformationFilter(d,
	                                              new StringSink(plainOut)
	                                              , BlockPaddingSchemeDef::ONE_AND_ZEROS_PADDING
	                                              , true
	               )
	);
	UE_LOG(LogTemp, Warning, TEXT(" the recovered:%s"), UTF8_TO_TCHAR(plainOut.c_str()));
	return UTF8_TO_TCHAR(plainOut.c_str());
}
#pragma endregion

如果还看不懂直接看gitee上代码吧。。。。
https://gitee.com/python3x/ue4-aes

相关标签: UE4 ue4 AES