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