UE4.26调用CryptoPP8.6库实现加密解密


前言

在UE4项目中用到CryptoPP库进行加密解密,但UE4内置CryptoPP库只有Crypto++5.65、Crypto++5.62两个版本,使用过程中会出现好多漏洞,这在新版本已经修复,所以只能升级到最新版Crypto++8.6,本文主要使用Crypto++8.6编译的lib库,在unreal中调用使用。


一、环境

win10
Crypto++ 8.6 (Crypto++下载地址)
unreal 4.26.2
vs2017

二、使用步骤

1.下载Crypto++ 8.6并打开

任意选择一个版本下载,这里选择美国原版。
在这里插入图片描述
下载以后解压到文件夹中,使用VS打开工程文件cryptest.sln
在这里插入图片描述
打开CryptoPP工程文件,会发现有四个子项目:

  • cryptdll - 生成cryptopp.dll动态库
  • dlltest - 用来测试cryptopp.dll,依赖cryptdll项目
  • cryptlib - 生成cryptlib.lib静态库
  • cryptest - 用来测试cryptopp,依赖cryptlib项目
    所以,我们有两种使用CryptoPP方法,一种是静态链接(MT),还有一种是动态链接(MD),使用对应的工程编译即可。因为UE4默认使用动态编译,我们下文以动态链接为例。
    在这里插入图片描述

2.编译cryptlib

右键cryptest和crylib属性,C/C++ ——> 代码生成 ——> 运行库 设置为 DLL(/MD)
这里写图片描述

选择 release x64编译
可以在“cryptopp860\x64\Output\Release”路径下找到cryptlib.lib
下文开始测试使用CryptoPP,实际使用中,如果功能上逻辑上需要修改,可以参考上文测试工程中的示例程序,以及官方文档。下文编译如果报告XX重复定义等错误,请检查LIB库工程和本测试工程的:C/C++ ——> 代码生成 ——> 运行库是否统一。

3.为项目拷贝必要文件

  • 使用UE4现有工程或新建一个工程,打开工程目录,
  • 将 cryptlib.lib拷贝到“工程名XXX\ThirdParty\crypto\lib\Win64\”,如果没有文件夹,请自行建立。
  • 将cryptopp860源代码的.h头文件全部拷贝到“工程名XXX\ThirdParty\crypto\include\Win64\”,如果没有文件夹,请自行建立。

4.将库引入到项目中

UE4模块引入第三方库,只要在Build.cs中配置头文件路径及添加lib文件即可。
在这里插入图片描述

//~~~和之前一样,此处代码不变
	DynamicallyLoadedModuleNames.AddRange(
		new string[]
		{
			// ... add any modules that your module loads dynamically here ...
		}
		);
	//此处开始配置第三方库crypto,这里的路径是工程目录,一定跟工程目录吻合,否则会各种报错。
        string cryptoPath = ModuleDirectory + "../../../ThirdParty/crypto/";
        if (Target.Platform == UnrealTargetPlatform.Win64)
        {
        	string platform = "/Win64/";
        	PublicIncludePaths.Add(cryptoPath + "include" + platform);
        	// PublicLibraryPaths.Add(cryptoPath + "lib" + platform);	//使用这个方法会警告
        	PublicSystemLibraryPaths.Add(cryptoPath + "lib" + platform);
        	PublicAdditionalLibraries.Add("cryptlib.lib");
            bUseRTTI = true;	//不加这行,解密的时候会报错
        }

虽然添加了十几行代码,但重要的代码就三行

PublicIncludePaths.Add(cryptoPath + “include” + platform); //此行是把(.h)头文件路径引入。
PublicLibraryPaths.Add(cryptoPath + “lib” + platform); //此行是把(.lib)库文件路径引入。
PublicAdditionalLibraries.Add(“cryptoPath .lib”); //此行是把(.lib)库文件引入。
之后就可以在你的代码中#include 第三方的(.h)文件,使用其中的功能了。

5.创建UE4接口文件

  • UE4中添加C++文件,继承于BlueprintFunctionLibrary类

在这里插入图片描述

  • 命名为AESBPLibrary

在这里插入图片描述

  • AESBPLibrary.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "AESBPLibrary.generated.h"

/**
 * 
 */
UCLASS()
class PRO13_API UAESBPLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

	///ECB mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "ECB_AESEncryptData_H", Keywords = "ECB_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF"), Category = "AES")
        static FString ECB_AESEncryptData(FString aes_content, FString aes_key);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "ECB_AESDecryptData_H", Keywords = "ECB_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF"), Category = "AES")
        static FString ECB_AESDecryptData(FString aes_content, FString aes_key, bool & result);

    ///CBC mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CBC_AESEncryptData_H", Keywords = "CBC_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CBC_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CBC_AESDecryptData", Keywords = "CBC_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CBC_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result);

    ///CBC_CTS mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CBC_CTS_AESEncryptData", Keywords = "CBC_CTS_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CBC_CTS_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CBC_CTS_AESDecryptData", Keywords = "CBC_CTS_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CBC_CTS_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result);

    ///CFB mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CFB_AESEncryptData", Keywords = "CFB_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CFB_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CFB_AESDecryptData", Keywords = "CFB_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CFB_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result);

    ///OFB mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "OFB_AESEncryptData", Keywords = "OFB_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString OFB_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "OFB_AESDecryptData", Keywords = "OFB_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString OFB_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result);

    ///CTR mode
    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CTR_AESEncryptData", Keywords = "CTR_AESEncryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CTR_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV);

    UFUNCTION(BlueprintCallable, meta = (DisplayName = "CTR_AESDecryptData", Keywords = "CTR_AESDecryptData", aes_key = "0123456789ABCDEF0123456789ABCDEF", aes_IV = "ABCDEF0123456789"), Category = "AES")
        static FString CTR_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result);

};
  • AESBPLibrary.cpp
// Fill out your copyright notice in the Description page of Project Settings.


#include "AESBPLibrary.h"

#include "string.h"
//这里使用工程目录,不是UE4安装目录
#include "../../../ThirdParty/crypto/include/Win64/aes.h"
#include "../../../ThirdParty/crypto/include/Win64/hex.h"
#include "../../../ThirdParty/crypto/include/Win64/modes.h"

using namespace std;
using namespace CryptoPP;




UAESBPLibrary::UAESBPLibrary(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{

}


#pragma region ECB

FString UAESBPLibrary::ECB_AESEncryptData(FString aes_content, FString aes_key)
{

	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;


	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);


	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	ECB_Mode_ExternalCipher::Encryption ecbEncryption(aesEncryption);
	StreamTransformationFilter ecbEncryptor(
		ecbEncryption,
		new HexEncoder(new StringSink(outstr)),
		BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING
	);
	ecbEncryptor.Put((byte *)plainText, strlen(plainText));
	ecbEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());

}


FString UAESBPLibrary::ECB_AESDecryptData(FString aes_content, FString aes_key, bool & result)
{

	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;
	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		ECB_Mode<AES >::Decryption ecbDecryption((byte *)key, AES::MAX_KEYLENGTH);

		HexDecoder decryptor(new StreamTransformationFilter(ecbDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING
		));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();
		result = true;
	}
	catch (const std::exception& e)
	{
		outstr = "error";
		outstr = e.what();
		UE_LOG(LogTemp, Error, TEXT("ECB_AESDecryptData failed!"));
		result = false;
	}
	return UTF8_TO_TCHAR(outstr.c_str());
}
#pragma endregion

#pragma region CBC


FString UAESBPLibrary::CBC_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV)
{
	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

	//填iv    
	byte iv[AES::BLOCKSIZE];
	memset(iv, 0x30, AES::BLOCKSIZE);
	sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);

	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);

	StreamTransformationFilter cbcEncryptor(cbcEncryption, new HexEncoder(new StringSink(outstr)), BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING);
	cbcEncryptor.Put((byte *)plainText, strlen(plainText));
	cbcEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());
}

FString UAESBPLibrary::CBC_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result)
{
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		//填iv    
		byte iv[AES::BLOCKSIZE];
		memset(iv, 0x30, AES::BLOCKSIZE);
		sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);


		CBC_Mode<AES >::Decryption cbcDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);

		HexDecoder decryptor(new StreamTransformationFilter(cbcDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::ONE_AND_ZEROS_PADDING));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();

		result = true;
	}
	catch (const std::exception&)
	{
		outstr = "error";
		UE_LOG(LogTemp, Error, TEXT("CBC_AESDecryptData failed!"));
		result = false;
	}

	return UTF8_TO_TCHAR(outstr.c_str());

}
#pragma endregion

#pragma region CBC_CTS


FString UAESBPLibrary::CBC_CTS_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV)
{
	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

	//填iv    
	byte iv[AES::BLOCKSIZE];
	memset(iv, 0x30, AES::BLOCKSIZE);
	sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);

	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	CBC_CTS_Mode_ExternalCipher::Encryption cbcctsEncryption(aesEncryption, iv);

	StreamTransformationFilter cbcctsEncryptor(cbcctsEncryption, new HexEncoder(new StringSink(outstr)), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING);
	cbcctsEncryptor.Put((byte *)plainText, strlen(plainText));
	cbcctsEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());
}

FString UAESBPLibrary::CBC_CTS_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result)
{
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		//填iv    
		byte iv[AES::BLOCKSIZE];
		memset(iv, 0x30, AES::BLOCKSIZE);
		sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);


		CBC_CTS_Mode<AES >::Decryption cbcctsDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);

		HexDecoder decryptor(new StreamTransformationFilter(cbcctsDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();

		result = true;
	}
	catch (const std::exception&)
	{
		outstr = "error";
		UE_LOG(LogTemp, Error, TEXT("CBC_CTS_AESDecryptData failed!"));
		result = false;
	}
	return UTF8_TO_TCHAR(outstr.c_str());
}
#pragma endregion

#pragma region CFB

FString UAESBPLibrary::CFB_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV)
{
	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

	//填iv    
	byte iv[AES::BLOCKSIZE];
	memset(iv, 0x30, AES::BLOCKSIZE);
	sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);

	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	CFB_Mode_ExternalCipher::Encryption cfbEncryption(aesEncryption, iv);

	StreamTransformationFilter cfbEncryptor(cfbEncryption, new HexEncoder(new StringSink(outstr)), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING);
	cfbEncryptor.Put((byte *)plainText, strlen(plainText));
	cfbEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());
}

FString UAESBPLibrary::CFB_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result)
{
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		//填iv    
		byte iv[AES::BLOCKSIZE];
		memset(iv, 0x30, AES::BLOCKSIZE);
		sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);


		CFB_Mode<AES >::Decryption cfbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);

		HexDecoder decryptor(new StreamTransformationFilter(cfbDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();

		result = true;
	}
	catch (const std::exception&)
	{
		outstr = "error";
		UE_LOG(LogTemp, Error, TEXT("CFB_AESDecryptData failed!"));
		result = false;
	}
	return UTF8_TO_TCHAR(outstr.c_str());
}
#pragma endregion

#pragma region OFB

FString UAESBPLibrary::OFB_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV)
{
	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

	//填iv    
	byte iv[AES::BLOCKSIZE];
	memset(iv, 0x30, AES::BLOCKSIZE);
	sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);

	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	OFB_Mode_ExternalCipher::Encryption ofbEncryption(aesEncryption, iv);

	StreamTransformationFilter ofbEncryptor(ofbEncryption, new HexEncoder(new StringSink(outstr)), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING);
	ofbEncryptor.Put((byte *)plainText, strlen(plainText));
	ofbEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());
}

FString UAESBPLibrary::OFB_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result)
{
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		//填iv    
		byte iv[AES::BLOCKSIZE];
		memset(iv, 0x30, AES::BLOCKSIZE);
		sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);


		OFB_Mode<AES >::Decryption ofbDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);

		HexDecoder decryptor(new StreamTransformationFilter(ofbDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();

		result = true;
	}
	catch (const std::exception&)
	{
		outstr = "error";
		UE_LOG(LogTemp, Error, TEXT("OFB_AESDecryptData failed!"));
		result = false;
	}
	return UTF8_TO_TCHAR(outstr.c_str());
}
#pragma endregion

#pragma region CTR

FString UAESBPLibrary::CTR_AESEncryptData(FString aes_content, FString aes_key, FString aes_IV)
{
	//std::string sKey = "0123456789ABCDEF0123456789ABCDEF";
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *plainText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	//填key    
	SecByteBlock key(AES::MAX_KEYLENGTH);
	memset(key, 0x30, key.size());
	sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

	//填iv    
	byte iv[AES::BLOCKSIZE];
	memset(iv, 0x30, AES::BLOCKSIZE);
	sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);

	AES::Encryption aesEncryption((byte *)key, AES::MAX_KEYLENGTH);

	CTR_Mode_ExternalCipher::Encryption ctrEncryption(aesEncryption, iv);

	StreamTransformationFilter ctrEncryptor(ctrEncryption, new HexEncoder(new StringSink(outstr)), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING);
	ctrEncryptor.Put((byte *)plainText, strlen(plainText));
	ctrEncryptor.MessageEnd();

	return UTF8_TO_TCHAR(outstr.c_str());
}

FString UAESBPLibrary::CTR_AESDecryptData(FString aes_content, FString aes_key, FString aes_IV, bool & result)
{
	std::string sKey = TCHAR_TO_UTF8(*aes_key);
	std::string sIV = TCHAR_TO_UTF8(*aes_IV);
	const char *cipherText = TCHAR_TO_ANSI(*aes_content);
	std::string outstr;

	try
	{
		//填key    
		SecByteBlock key(AES::MAX_KEYLENGTH);
		memset(key, 0x30, key.size());
		sKey.size() <= AES::MAX_KEYLENGTH ? memcpy(key, sKey.c_str(), sKey.size()) : memcpy(key, sKey.c_str(), AES::MAX_KEYLENGTH);

		//填iv    
		byte iv[AES::BLOCKSIZE];
		memset(iv, 0x30, AES::BLOCKSIZE);
		sIV.size() <= AES::BLOCKSIZE ? memcpy(iv, sIV.c_str(), sIV.size()) : memcpy(iv, sIV.c_str(), AES::BLOCKSIZE);


		CTR_Mode<AES >::Decryption ctrDecryption((byte *)key, AES::MAX_KEYLENGTH, iv);

		HexDecoder decryptor(new StreamTransformationFilter(ctrDecryption, new StringSink(outstr), BlockPaddingSchemeDef::BlockPaddingScheme::NO_PADDING));
		decryptor.Put((byte *)cipherText, strlen(cipherText));
		decryptor.MessageEnd();

		result = true;
	}
	catch (const std::exception&)
	{
		outstr = "error";
		UE_LOG(LogTemp, Error, TEXT("CTR_AESDecryptData failed!"));
		result = false;
	}
	return UTF8_TO_TCHAR(outstr.c_str());
}
#pragma endregion

编译成功没有报错就可以在蓝图中调用了

6.蓝图调用

  • 在关卡蓝图中调用相应接口进行加密解密
    在这里插入图片描述
  • 运行测试
    在这里插入图片描述
    成功输出。

三、总结

  • 心得:
    在实际操作中主要解决报错的问题,大多是因为Crypt++工程运行库和本工程运行库不一致或者是引用库文件目录有误所造成的,需要仔细检查核对。
    以上就是今天要讲的内容,本文仅仅简单介绍了UE4使用外部lib库的使用,如果需要将lib库添加到插件中也是可以的,在此不多赘述。
  • 本文参考:
    https://blog.csdn.net/lyg920/article/details/51543346
    https://blog.csdn.net/Szu_IT_Man/article/details/78790408
    https://blog.csdn.net/qq_33042187/article/details/115446197
    https://blog.csdn.net/l2543767402/article/details/89792336
    在此,非常感谢以上几位大神的指引,文中有部分是摘抄大神手笔,请勿怪。
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Crypto++(也叫CryptoPP)是一款非常方便的C++加密,可以用于AES加密解密。以下是简单的示例代码: AES加密: ```cpp #include <cryptopp/aes.h> #include <cryptopp/modes.h> #include <cryptopp/filters.h> std::string plaintext = "Hello World!"; std::string key = "mysecretkey"; std::string iv = "myivalue"; CryptoPP::AES::Encryption aesEncryption((byte*)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (byte*)iv.c_str()); std::string ciphertext; CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(ciphertext)); stfEncryptor.Put(reinterpret_cast<const unsigned char*>(plaintext.c_str()), plaintext.length()+1); stfEncryptor.MessageEnd(); std::string encrypted = CryptoPP::base64_encode(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.length()); ``` AES解密: ```cpp #include <cryptopp/aes.h> #include <cryptopp/modes.h> #include <cryptopp/filters.h> std::string encrypted = "encrypted"; std::string key = "mysecretkey"; std::string iv = "myivalue"; std::string ciphertext = CryptoPP::base64_decode(encrypted); CryptoPP::AES::Decryption aesDecryption((byte*)key.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, (byte*)iv.c_str()); std::string decrypted; CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); stfDecryptor.Put(reinterpret_cast<const unsigned char*>(ciphertext.c_str()), ciphertext.size()); stfDecryptor.MessageEnd(); ``` 需要注意的是,Crypto++需要自行安装并配置,但它提供了丰富的加密算法,使用方便,是一款广泛应用的C++加密

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值