2011-12-05 13 views
1

暗号化文字列をC#プログラムからC++プログラムへのTCP接続経由で送信しようとしています。 C++プログラムは、文字列の復号化を試みるときにcrypto ++でクラッシュします。デバッガで文字列がほとんどデコードされているが、正しく終了していないことがわかります。たとえば、私は、 "Hello World" のそれのように復号化されます送信した場合、 "こんにちは、@#$ @#%%の世界"(末尾のゴミ)解読するためにC#AES暗号化文字列をCyptoPP C++プログラムに送信

ここ

は私が

  //Create byte arrays to hold original, encrypted, and decrypted data. 
       byte[] dataToEncrypt = ByteConverter.GetBytes(data); 

       byte[] key = new byte[16]; 
       for (int i = 0; i < 16; ++i) 
       { 
        key[i] = 1; 
       } 

       byte[] iv = new byte[16]; 
       for (int i = 0; i < 16; ++i) 
       { 
        iv[i] = 1; 
       } 


       RijndaelManaged myRijndael = new RijndaelManaged(); 

       myRijndael.Key = key; 
       myRijndael.IV = iv; 
       byte[] encrypted = encryptStringToBytes_AES(data, myRijndael.Key, myRijndael.IV); 

     // sends the byte array via active tcp connection 
     _transport.SendEncryptedData(encrypted); 


static byte[] encryptStringToBytes_AES(string plainText, byte[] Key, byte[] IV) 
{ 
    // Check arguments. 
      if (plainText == null || plainText.Length <= 0) 
       throw new ArgumentNullException("plainText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("IV"); 

      // Declare the stream used to encrypt to an in memory 
      // array of bytes. 
      MemoryStream msEncrypt = null; 

      // Declare the RijndaelManaged object 
      // used to encrypt the data. 
      RijndaelManaged aesAlg = null; 

      try 
      { 
       // Create a RijndaelManaged object 
       // with the specified key and IV. 
       aesAlg = new RijndaelManaged(); 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 

       // Create an encrypto to perform the stream transform. 
       ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); 

       // Create the streams used for encryption. 
       msEncrypt = new MemoryStream(); 
       using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) 
       { 
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) 
        { 
         //Write all data to the stream. 
         swEncrypt.Write(plainText); 
        } 
       } 
      } 
      finally 
      { 
       // Clear the RijndaelManaged object. 
       if (aesAlg != null) 
        aesAlg.Clear(); 
      } 

      // Return the encrypted bytes from the memory stream. 
      return msEncrypt.ToArray(); 
     } 

はここでC++側の復号化だ暗号化する方法を説明します暗号を持つ++

 byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ]; 
     byte iv[ CryptoPP::AES::BLOCKSIZE ]; 
     ::memset(key, 0x01, CryptoPP::AES::DEFAULT_KEYLENGTH); 
     ::memset(iv, 0x01, CryptoPP::AES::BLOCKSIZE); 

     std::string decryptedtext; 


     CryptoPP::AES::Decryption aesDecryption(key, CryptoPP::AES::DEFAULT_KEYLENGTH); 
     CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv); 


     CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decryptedtext)); 

      // CRASHES IN .PUT(...) 
     stfDecryptor.Put(reinterpret_cast<const unsigned char*>(data), len + 1); 
     stfDecryptor.MessageEnd(); 

答えて

1

2つのうちの1つ、おそらくは両方の問題が原因です。

  1. C#ストリームライターはヌルバイトを書き出しません。 C++コードがデータを読み込むと、文字列はnullで終了しません。あなたが与えたコードはテストしていませんが、これは予想される動作のようです。

  2. パディング(またはその欠落)の想定される方法は、C#実装とCrypto ++実装で異なる場合があります。 CBCモードのAESは、ブロックサイズの倍数であるブロックのみを暗号化または復号化できます。 AESでは、ブロックサイズは128ビットまたは16バイトです。

ウィキペディアには、さまざまなブロック暗号モードhereの説明があります。 CBCの典型的なパディングはPKCS7であり、これはhereと記載されています。

パディングのデフォルトメソッドが何であるかを知るのに十分なだけでなく、ユーザーにそれを任せているかどうかはわかりません。

+0

RijndaelManagedのデフォルトはPaddingMode.PKCS7です。 CryptoPPのデフォルトはDEFAULT_PADDING ...それ以上は見つかりませんでした。この回答の行に沿って、StreamTransformationFilterを変更して、Paddingのオプションの第3パラメータを持ち、PKCSオプションを設定することをお勧めします。 –

+0

"DEFAULT_PADDINGはならc.MandatoryBlockSize()> 1 && c.MinLastBlockSize()== 0(例えばECBあるいはCBCモード)、そうでなければNO_PADDING(OFB、CFB、CTR、CBC-CTSモード)PKCS_PADDINGを意味します。" [リンク](http://www.cryptopp.com/docs/ref/class_stream_transformation_filter.html)したがって、PKCSを使用する必要があります。私はそれがヌルターミネーターだと賭けている、私はそれについてもっと考える。 – Luke

関連する問題