AES暗号化処理をC#からC++に変換したい


C#でAES暗号化していた処理をC++でも利用するために変換を試みているのですが、Crypto++ライブラリを使っての実装ができません。  
暗号化はできているようなのですが、結果が異なってしまいます。

ブロックサイズとキーサイズの指定が怪しいと考えているのですが、どこが要因かわかる方ご教授願えますでしょうか。

C# Code

[code]

    const string AesIV = @"1234567890123456";
    const string AesKey = @"ABCDEFGHIJKLMNOP";
    string strText = "暗号化テスト";
    
    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
    aes.BlockSize = 128;
    aes.KeySize = 128;
    aes.IV = Encoding.UTF8.GetBytes(AesIV);
    aes.Key = Encoding.UTF8.GetBytes(AesKey);
    aes.Mode = CipherMode.CBC;
    aes.Padding = PaddingMode.PKCS7;
    byte[] byteText = Encoding.UTF8.GetBytes(strText);
    
    byte[] encryptText = aes.CreateEncryptor().TransformFinalBlock(byteText, 0, byteText.Length);
    
[/code]

C++ Code (Crypto++利用)

[code]

    std::string strKey("1234567890123456");
    std::string strIV("ABCDEFGHIJKLMNOP");
    std::string strText = "暗号化テスト";
    
    std::string stEncryptText;
    
    CryptoPP::AES::Encryption aesEncryption((CryptoPP::byte*)strKey.c_str(), CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, (CryptoPP::byte*)strIV.c_str());
    
    CryptoPP::StreamTransformationFilter stfEncryptor(cbcEncryption, new CryptoPP::StringSink(stEncryptText), CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING);
    stfEncryptor.Put(reinterpret_cast<const unsigned char*>(strText.c_str()), strText.length());
    stfEncryptor.MessageEnd();
    
[/code]




>
[code]

>     // C#
>     byte[] byteText = Encoding.UTF8.GetBytes(strText);
>  
>     // C++
>     std::string strText = "暗号化テスト";
>  
[/code]

C#は見ての通りUTF-8エンコーディングのバイト列となります。Visual
StudioのC++とのことですが、こちらはコントロールパネルの「Unicode
対応ではないプログラムの言語」の設定値で日本語環境ではShift_JISエンコーディングとなります。このため、入力バイト列がそもそも異なります。

UTF-8で一致させるには[UTF-8文字列リテラル](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)が簡単ですがお使いのVisual
Studio 2013では未対応です。Visual Studio
2015以降を使用されるか、[wctomb](https://docs.microsoft.com/ja-jp/cpp/c-runtime-
library/reference/wctomb-wctomb-l?view=vs-2019)等で変換することになります。

[code]

    // C#
    byte[] byteText = Encoding.UTF8.GetBytes(strText);
    // C++
    std::string strText = u8"暗号化テスト";
    
[/code]

「Unicode
対応ではないプログラムの言語」で一致させるには[Encoding.Default](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.encoding.default?view=netframework-4.8)を使用します。

[code]

    // C#
    byte[] byteText = Encoding.Default.GetBytes(strText);
    // C++
    std::string strText = "暗号化テスト";
    
[/code]

* * *

> ソースコードのエンコーディングをUTF-8（プロパティのC++コマンドラインで指定）にしてみましたが変わらずでした。

補足しますと、Visual
C++ではソースコードを解釈し一旦Unicodeに変換しています。その上で、指定されたエンコーディングのバイト列に変換してコード生成しています。そのため、ソースコードがUTF-8エンコーディングであっても
`""` 文字列は **コンパイル環境** の「Unicode
対応ではないプログラムの言語」に沿ったバイト列（すなわち日本語環境においてはShift_JIS）となります。

一方、C#の`Encoding.Default`は **実行環境** の「Unicode
対応ではないプログラムの言語」に沿ったバイト列となります。同じ設定でも参照するタイミングが異なる点には気を付ける必要があります。




>
[code]

>     // C#
>     byte[] byteText = Encoding.UTF8.GetBytes(strText);
>  
>     // C++
>     std::string strText = "暗号化テスト";
>  
[/code]

C#は見ての通りUTF-8エンコーディングのバイト列となります。Visual
StudioのC++とのことですが、こちらはコントロールパネルの「Unicode
対応ではないプログラムの言語」の設定値で日本語環境ではShift_JISエンコーディングとなります。このため、入力バイト列がそもそも異なります。

UTF-8で一致させるには[UTF-8文字列リテラル](https://cpprefjp.github.io/lang/cpp11/utf8_string_literals.html)が簡単ですがお使いのVisual
Studio 2013では未対応です。Visual Studio
2015以降を使用されるか、[wctomb](https://docs.microsoft.com/ja-jp/cpp/c-runtime-
library/reference/wctomb-wctomb-l?view=vs-2019)等で変換することになります。

[code]

    // C#
    byte[] byteText = Encoding.UTF8.GetBytes(strText);
    // C++
    std::string strText = u8"暗号化テスト";
    
[/code]

「Unicode
対応ではないプログラムの言語」で一致させるには[Encoding.Default](https://docs.microsoft.com/ja-
jp/dotnet/api/system.text.encoding.default?view=netframework-4.8)を使用します。

[code]

    // C#
    byte[] byteText = Encoding.Default.GetBytes(strText);
    // C++
    std::string strText = "暗号化テスト";
    
[/code]

* * *

> ソースコードのエンコーディングをUTF-8（プロパティのC++コマンドラインで指定）にしてみましたが変わらずでした。

補足しますと、Visual
C++ではソースコードを解釈し一旦Unicodeに変換しています。その上で、指定されたエンコーディングのバイト列に変換してコード生成しています。そのため、ソースコードがUTF-8エンコーディングであっても
`""` 文字列は **コンパイル環境** の「Unicode
対応ではないプログラムの言語」に沿ったバイト列（すなわち日本語環境においてはShift_JIS）となります。

一方、C#の`Encoding.Default`は **実行環境** の「Unicode
対応ではないプログラムの言語」に沿ったバイト列となります。同じ設定でも参照するタイミングが異なる点には気を付ける必要があります。

