UE4 CryptoPP 5.6.5 加解密
Crypto++ 5.6.5
密码与偏移量:
static SecByteBlock GetKey(std::string KeyStr) { 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; } //convert string to byte static SecByteBlock GetIV(std::string KeyStr, const std::string IVStr) { 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; }
加解密过程(包含输出 string 及 file):
UFUNCTION(BlueprintCallable, Category = "AES") static void CBC_StringEncrypto(const FString aes_content, FString& aes_encrypt_content, const FString aes_key = TEXT("1234567890123456"), const FString aes_IV = TEXT("ahbdgteyusnjkldu")) { const std::string plaintext = TCHAR_TO_UTF8(*aes_content); // Initialise the key and IV SecByteBlock key = GetKey(TCHAR_TO_UTF8(*aes_key)); SecByteBlock iv = GetIV(TCHAR_TO_UTF8(*aes_key), TCHAR_TO_UTF8(*aes_IV)); // Encrypt AES::Encryption cipher(key, AES::MAX_KEYLENGTH); CBC_Mode_ExternalCipher::Encryption encryption(cipher, iv); std::string cipher_text; StreamTransformationFilter filter(encryption, new StringSink(cipher_text)); //使用填充并通过 HexEncoder 编码将 cipher_text 密文转成可以正常打印阅读的密文,但是无法正常解码?????????? //StreamTransformationFilter filter(encryption, new HexEncoder(new StringSink(cipher_text)), BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING); filter.Put(reinterpret_cast<const byte*>(plaintext.c_str()), plaintext.size()); filter.MessageEnd(); //存输出的 string 密文 std::string cipherOut; StringSource(cipher_text, true, new HexEncoder(new StringSink(cipherOut))); //to lower //std::string str = _strlwr(TCHAR_TO_ANSI((UTF8_TO_TCHAR(cipher_text.c_str())))); aes_encrypt_content = cipherOut.c_str(); } UFUNCTION(BlueprintCallable, Category = "AES") static void CBC_StringDecrypto(const FString aes_encrypt_content, FString& aes_content, const FString aes_key = TEXT("1234567890123456"), const FString aes_IV = TEXT("ahbdgteyusnjkldu")) { //存明文 std::string cipher_text; //对密文先进行 Decoder 为明文 StringSource(TCHAR_TO_UTF8(*aes_encrypt_content), true, new HexDecoder(new StringSink(cipher_text))); //存输出的 string 明文 std::string decrypted_text; //Initialise the key and IV SecByteBlock key = GetKey(TCHAR_TO_UTF8(*aes_key)); SecByteBlock iv = GetIV(TCHAR_TO_UTF8(*aes_key), TCHAR_TO_UTF8(*aes_IV)); // Decrypt AES::Decryption cipher(key, AES::MAX_KEYLENGTH); CBC_Mode_ExternalCipher::Decryption decryption(cipher, iv); StreamTransformationFilter filter(decryption, new StringSink(decrypted_text)); //使用填充并通过 HexEncoder 编码将 cipher_text 密文转成可以正常阅读的明文,无法正常解码使用?????????? //StreamTransformationFilter filter(decryption, new HexEncoder(new StringSink(decrypted_text)), BlockPaddingSchemeDef::BlockPaddingScheme::ZEROS_PADDING); filter.Put(reinterpret_cast<const byte*>(cipher_text.c_str()), cipher_text.size()); filter.MessageEnd(); aes_content = UTF8_TO_TCHAR(decrypted_text.c_str()); } UFUNCTION(BlueprintCallable, Category = "AES") static void CBC_AESFileEncrypto(const FString aes_key = TEXT("1234567890123456"), const FString aes_IV = TEXT("ahbdgteyusnjkldu")) { FString OriginalPath = FPaths::ProjectContentDir() + "\\" + TEXT("original.txt"); const std::string original_file = TCHAR_TO_UTF8(*OriginalPath); FString EncryptPath = FPaths::ProjectContentDir() + "\\" + TEXT("encrypted.txt"); const std::string encrypto_file = TCHAR_TO_UTF8(*EncryptPath); // Initialise the key and IV SecByteBlock key = GetKey(TCHAR_TO_UTF8(*aes_key)); SecByteBlock iv = GetIV(TCHAR_TO_UTF8(*aes_key), TCHAR_TO_UTF8(*aes_IV)); // Read the file contents to a string and output to cout. Safest to read // contents as binary data, although non-printable characters shouldn't be // output to cout. std::ifstream infile(original_file.c_str(), std::ios::binary); const std::string plaintext((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>()); infile.close(); std::cout << "Plain Text (" << plaintext.size() << " bytes)\n" << plaintext << "\n\n"; // Encrypt AES::Encryption cipher(key, AES::MAX_KEYLENGTH); CBC_Mode_ExternalCipher::Encryption encryption(cipher, iv); std::string cipher_text; StreamTransformationFilter filter(encryption, new StringSink(cipher_text)); //使用填充并通过 HexEncoder 编码将 cipher_text 密文转成可以正常打印阅读的密文,但是无法正常解码?????????? //StreamTransformationFilter filter(encryption, new HexEncoder(new StringSink(cipher_text)), BlockPaddingSchemeDef::BlockPaddingScheme::PKCS_PADDING, true); filter.Put(reinterpret_cast<const byte*>(plaintext.c_str()), plaintext.size()); filter.MessageEnd(); //to lower //std::string str = _strlwr(TCHAR_TO_ANSI((UTF8_TO_TCHAR(cipher_text.c_str())))); // Dump cipher text std::ofstream outfile(encrypto_file.c_str(), std::ios::binary); outfile.write(cipher_text.c_str(), cipher_text.size()); outfile.close(); } UFUNCTION(BlueprintCallable, Category = "AES") static void CBC_AESFileDecrypto(const FString aes_key = TEXT("1234567890123456"), const FString aes_IV = TEXT("ahbdgteyusnjkldu")) { FString EncryptPath = FPaths::ProjectContentDir() + "\\" + TEXT("encrypted.txt"); const std::string encrypto_file = TCHAR_TO_UTF8(*EncryptPath); FString DecryptoPath = FPaths::ProjectContentDir() + "\\" + TEXT("decrypted.txt"); const std::string decrypto_file = TCHAR_TO_UTF8(*DecryptoPath); //Initialise the key and IV SecByteBlock key = GetKey(TCHAR_TO_UTF8(*aes_key)); SecByteBlock iv = GetIV(TCHAR_TO_UTF8(*aes_key), TCHAR_TO_UTF8(*aes_IV)); // Read the encrypted file contents to a string as binary data. std::ifstream infile(encrypto_file.c_str(), std::ios::binary); const std::string cipher_text((std::istreambuf_iterator<char>(infile)), std::istreambuf_iterator<char>()); infile.close(); // Decrypt CryptoPP::AES::Decryption cipher(key, AES::MAX_KEYLENGTH); CryptoPP::CBC_Mode_ExternalCipher::Decryption decryption(cipher, iv); std::string decrypted_test; StreamTransformationFilter filter(decryption, new CryptoPP::StringSink(decrypted_test)); //使用填充并通过 HexEncoder 编码将 cipher_text 密文转成可以正常阅读的明文,无法正常解码使用?????????? //StreamTransformationFilter filter(decryption, new HexEncoder(new StringSink(decrypted_test)), BlockPaddingSchemeDef::BlockPaddingScheme::PKCS_PADDING, true); filter.Put(reinterpret_cast<const byte*>(cipher_text.c_str()), cipher_text.size()); filter.MessageEnd(); // Dump decrypted text std::ofstream outfile(decrypto_file.c_str(), std::ios::binary); outfile.write(decrypted_test.c_str(), decrypted_test.size()); outfile.close(); }
Encrypto 及 Decrypto 都支持 DEFAULT_PADDING、NO_PADDING、ONE_AND_ZEROS_PADDING、PKCS_PADDING、ZEROS_PADDING,不设置 PADDING 参数(源码默认是 DEFAULT_PADDING)。
WEB AES 验证工具:
https://www.ssleye.com/ssltool/aes_cipher.html
https://www.javainuse.com/aesgenerator
https://the-x.cn/en-us/cryptography/Aes.aspx
相关话题:
http://elmagnifico.tech/2021/01/08/Crypto++-padding/
https://gameinstitute.qq.com/community/detail/121437
https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
https://www.codenong.com/43967330/
https://coderedirect.com/questions/212416/encrypt-decrypt-with-aes-using-c-c
https://*.com/questions/43967330/crypto-aes-256-ecb-result-is-different-with-openssl
https://blog.csdn.net/qq_35649764/article/details/83036230?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.highlightwordscore&spm=1001.2101.3001.4242.1
https://blog.csdn.net/suhiymof/article/details/92796811