个人使用 UE4 C++ 函数库(AES-ECB加密注册机)

个人使用 UE4 C++ 函数库(AES-ECB加密注册机)

加密使用CryptoPP5.6.5

build.cs

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

在这里插入图片描述在这里插入图片描述

include

#include <ThirdParty/CryptoPP/5.6.5/include/modes.h>
#include <ThirdParty/CryptoPP/5.6.5/include/hex.h>
#include <ThirdParty/CryptoPP/5.6.5/include/aes.h>
using namespace std;
using namespace CryptoPP;

.h

   // 复制到剪贴板
   UFUNCTION(BlueprintCallable, Category = "Registry")
      static void CopyToClipboard(FString text);

   // 获得机器码
   UFUNCTION(BlueprintPure, Category = "Registry")
      static void GetUniqueId(FString& UniqueId);

   // 获取HashAnsiString后的机器码
   UFUNCTION(BlueprintPure, Category = "Registry")
      static void GetHashAnsiId(FString& HashAnsiId);

   // 作用为使用AES-ECB加密解密
   UFUNCTION(BlueprintCallable, meta = (DisplayName = "ECB_AESEncryptData", Keywords = "ECB_AESEncryptData", aes_key = "default"), Category = "Registry")
      static FString ECB_AESEncryptData(FString aes_content, FString aes_key);

   UFUNCTION(BlueprintCallable, meta = (DisplayName = "ECB_AESDecryptData", Keywords = "ECB_AESDecryptData", aes_key = "default"), Category = "Registry")
      static FString ECB_AESDecryptData(FString aes_content, FString aes_key, bool& result);

.cpp


void cryptoTest::CopyToClipboard(FString text)
{
   FPlatformMisc::ClipboardCopy(*text);
}

void cryptoTest::GetUniqueId(FString& UniqueId)
{
   FString tempid;

   TArray<uint8> MacAddr = FPlatformMisc::GetMacAddress();

   for(TArray<uint8>::TConstIterator it(MacAddr); it; ++it)
   {
      tempid += FString::Printf(TEXT("%02x"), *it);
   }
   UniqueId = tempid;
}

void cryptoTest::GetHashAnsiId(FString& HashAnsiId)
{
   FString tempid;

   TArray<uint8> MacAddr = FPlatformMisc::GetMacAddress();

   for(TArray<uint8>::TConstIterator it(MacAddr); it; ++it)
   {
      tempid += FString::Printf(TEXT("%02x"), *it);
   }
   HashAnsiId = FMD5::HashAnsiString(*tempid);
}


//会报错,先不用
FString cryptoTest::ECB_AESEncryptData(FString aes_content, FString aes_key)
{
   std::string sKey = TCHAR_TO_UTF8(*aes_key);
   const char* plainText = TCHAR_TO_ANSI(*aes_content);
   std::string outstr;

   if(aes_key == "default" || aes_key.IsEmpty())
   {
      //设定默认秘钥,只要是32位的16进制数随便写
      sKey = "01010101010101010101010101010101";
   }

   //填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)));
   StreamTransformationFilter ecbEncryptor(
      ecbEncryption,
      new HexEncoder(new StringSink(outstr)),
      BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING,
      true
   );
   ecbEncryptor.Put((byte*)plainText, strlen(plainText));
   ecbEncryptor.MessageEnd();
   FString returnValue = UTF8_TO_TCHAR(outstr.c_str());
   return returnValue;
}

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

   std::string sKey = TCHAR_TO_UTF8(*aes_key);
   std::string outstr;
   std::string cipherText = TCHAR_TO_UTF8(*aes_content);
   result = false;

   if(aes_key == "default" || aes_key.IsEmpty())
   {
      //设定默认秘钥,只要是32位的16进制数随便写
      sKey = "01010101010101010101010101010101";
   }
   //判断是否为空指针
   if(aes_content.IsEmpty())
   {
      result = false;
      return "0";
   }
   //判断是否为16为长度倍数
   if(cipherText.size() % 16 != 0)
   {
      // CipherText is not a multiple of 2, which means it is not a valid hexadecimal string
      result = false;
      return "0";
   }
   //验证是否为16进制字符
   // Check if all characters in the cipherText are valid hexadecimal characters
   for(char c : cipherText)
   {
      if(!isxdigit(c))
      {
         result = false;
         return "0";
      }
   }

   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);

      //加上 "true" 后可以验证,但是如果验证失败可能会闪退
      //HexDecoder decryptor(new StreamTransformationFilter(ecbDecryption, new StringSink(outstr)));
      HexDecoder decryptor(new StreamTransformationFilter(
         ecbDecryption, new StringSink(outstr),
         BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING,
         true
      ));
      decryptor.Put((byte*)cipherText.c_str(), cipherText.size());
      decryptor.MessageEnd();
      result = true;
   }
   catch(const Exception& e)
   {
      // An exception occurred, set the result to false and log the error
      outstr = "0";
      UE_LOG(LogTemp, Error, TEXT("ECB_AESDecryptData failed: %s"), ANSI_TO_TCHAR(e.what()));
      result = false;
   }
   FString returnValue = UTF8_TO_TCHAR(outstr.c_str());
   return returnValue;
}

在这里插入图片描述

在这里插入图片描述

警告: 这是一个解密函数,但当输入值(cipherText)非法时,该函数可能会导致UE4闪退,因此请提前对输入的值进行判断

      HexDecoder decryptor(new StreamTransformationFilter(
         ecbDecryption, new StringSink(outstr),
         BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING,
         true
      ));

当编译失败时,有可能是因为导入出现问题,可以在.cpp文件中使用以下代码包裹CryptoPP并重试

THIRD_PARTY_INCLUDES_START
#if PLATFORM_WINDOWS

#include <ThirdParty/CryptoPP/5.6.5/include/modes.h>
#include <ThirdParty/CryptoPP/5.6.5/include/hex.h>
#include <ThirdParty/CryptoPP/5.6.5/include/aes.h>
#elif PLATFORM_MAC
#elif PLATFORM_LINUX
#endif
THIRD_PARTY_INCLUDES_END

示例:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉小兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值