2016-04-14 30 views
0

ファイルをAESで暗号化しようとしています。検索して、this C# sampleを見つけました。これをC++/CLIに変換する試みです。AESファイルの暗号化がC++/CLIで機能しない

using namespace System; 
using namespace System::IO; 
using namespace System::Security::Cryptography; 

void DecryptFile(String^ sourceFilename, String^ destinationFilename, String^ password, array<Byte>^ salt, int iterations){ 
try{ 
    RijndaelManaged^ aes = gcnew RijndaelManaged(); 
    aes->BlockSize = aes->LegalBlockSizes[0]->MaxSize; 
    aes->KeySize = aes->LegalKeySizes[0]->MaxSize; 
    // NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides. 
    Rfc2898DeriveBytes ^key = gcnew Rfc2898DeriveBytes(password, salt, iterations); 
    aes->Key = key->GetBytes(aes->KeySize/8); 
    aes->IV = key->GetBytes(aes->BlockSize/8); 
    aes->Mode = CipherMode::CBC; 
    ICryptoTransform^ transform = aes->CreateDecryptor(aes->Key, aes->IV); 

    FileStream^ destination = gcnew FileStream(destinationFilename, FileMode::OpenOrCreate, FileAccess::Write, FileShare::None); 
    CryptoStream^ cryptoStream = gcnew CryptoStream(destination, transform, CryptoStreamMode::Write); 
    FileStream^ source = gcnew FileStream(sourceFilename, FileMode::Open, FileAccess::Read, FileShare::Read); 
    source->CopyTo(cryptoStream); 
} 
catch (Exception^ exception){Console::WriteLine(exception->Message);} 
} 

void EncryptFile(String^ sourceFilename, String^ destinationFilename, String^ password, array<Byte>^ salt, int iterations){ 
try{ 
    RijndaelManaged^ aes = gcnew RijndaelManaged(); 
    aes->BlockSize = aes->LegalBlockSizes[0]->MaxSize; 
    aes->KeySize = aes->LegalKeySizes[0]->MaxSize; 
    // NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides. 
    Rfc2898DeriveBytes^ key = gcnew Rfc2898DeriveBytes(password, salt, iterations); 
    aes->Key = key->GetBytes(aes->KeySize/8); 
    aes->IV = key->GetBytes(aes->BlockSize/8); 
    aes->Mode = CipherMode::CBC; 
    ICryptoTransform^ transform = aes->CreateEncryptor(aes->Key, aes->IV); 

    FileStream^ destination = gcnew FileStream(destinationFilename, FileMode::OpenOrCreate, FileAccess::Write, FileShare::None); 
    CryptoStream^ cryptoStream = gcnew CryptoStream(destination, transform, CryptoStreamMode::Write); 
    FileStream^ source = gcnew FileStream(sourceFilename, FileMode::Open, FileAccess::Read, FileShare::Read); 
    source->CopyTo(cryptoStream); 
} 
catch(Exception^ exception){Console::WriteLine(exception->Message);} 
} 

int main(){ 
srand(time(NULL)); 
array<Byte>^ salt = gcnew array<Byte> { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Must be at least eight bytes. MAKE THIS SALTIER! 
int iterations=rand(); 
EncryptFile("C:\\Users\\test\\Desktop\\test.txt", "C:\\Users\\test\\Desktop\\test1.txt", "afckingpinecone.", salt, iterations); 
DecryptFile("C:\\Users\\test\\Desktop\\test1.txt", "C:\\Users\\test\\Desktop\\test2.txt", "afckingpinecone.", salt, iterations); 
return 0; 
} 

私は2つのファイルでテストしました。 1つの.pngと1つの平文。イメージは暗号化され、解読されたが、テキストファイルには表示されませんでした。元のファイルには15バイトのASCII文字列が含まれていますが、暗号化および復号化されたファイルは0バイトです。

+0

C#のプログラマーは、* using *ステートメントで成功のピットになる傾向があります。同じピットを見つけるには、[C++/CLIスタックセマンティクス](https://msdn.microsoft.com/en-us/library/ms177191.aspx)を学ばなければなりません。現状では、CryptoStream-> FlushFinalBlock()が存在しないため、delete cryptoStreamも呼び出されません。最後のブロックはありません。 –

+0

ありがとうございます。あなたが答えとして投稿したら、私はそれを受け入れるだろう –

+0

あなた自身が投稿し、あなたが使ったコードを表示し、それを受け入れてあなたの質問を閉じる。 –

答えて

0

ストリームを閉じるのを忘れて、暗号化/復号化機能の最後に次の行を挿入します。

cryptoStream->Close(); 
destination->Close();