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

UE4 CryptoPP 5.6.5 加解密

程序员文章站 2022-03-25 15:01:49
...

 

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