2016-10-25 6 views
0

Stegolayer()という名前のLSBステガノグラフィ機能があります。この機能には、データを非表示にすることがあります。私の元のデータはAESで暗号化されていて、outputに保存されています。私はファイルバイトハッシュコードとRSAで暗号化されたセッションキーを添付します。さまざまな部分で構成されるストリームを分割して結合する方法

私の組み込みシークレットは、効果的に、暗号化されたデータ+ハッシュコード&のセッションキーを1つのシングルバイトストリームとして構成します。それを抽出した後、どのようにこれらの2つの部分を分割できますか?

EncryptFile(pass_txt.Text, loadedFilePath, output); 
      fileContainer = File.ReadAllBytes(output); 
      hashcode = SHA256.Create().ComputeHash(File.ReadAllBytes(loadedFilePath)); 
      Newpassword = CreateRandomPassword(pass_txt.Text.Length); 
      Newpasswordbytes = Byteconverter.GetBytes(Newpassword); 
      RSAplain= Combine(hashcode,Newpasswordbytes); 
      RSAcipher = RSAencryption(RSAplain, RSA.ExportParameters(false), false); 
      bytestobehidden = Combine(fileContainer, RSAcipher); 
      fileSize = bytestobehidden.Length; 
      if (8 * ((height * (width/3) * 3)/3 - 1) < fileSize + fileNameSize) 
      { 
       MessageBox.Show("File size is too large!\nPlease use a larger image to hide this file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       return; 
      } 

      StegoLayer(); 

private byte[] Combine(byte[] a, byte[] b) 
    { 
     byte[] c = new byte[a.Length + b.Length]; 
     System.Buffer.BlockCopy(a, 0, c, 0, a.Length); 
     System.Buffer.BlockCopy(b, 0, c, a.Length, b.Length); 
     return c; 
    } 

public static void EncryptFile(string password, string in_file, string out_file) 
    { 
     CryptFile(password, in_file, out_file, true); 
    } 

    public static void DecryptFile(string password, string in_file, string out_file) 
    { 
     CryptFile(password, in_file, out_file, false); 
    } 
    public static void CryptFile(string password,string in_file, string out_file, bool encrypt) 
    { 
     // Create input and output file streams. 
     using (FileStream in_stream = 
      new FileStream(in_file, FileMode.Open, FileAccess.Read)) 
     { 
      using (FileStream out_stream = 
       new FileStream(out_file, FileMode.Create, 
        FileAccess.Write)) 
      { 
       // Encrypt/decrypt the input stream into 
       // the output stream. 
       CryptStream(password, in_stream, out_stream, encrypt); 
      } 
     } 
    } 
    // Encrypt the data in the input stream into the output stream. 
    public static void CryptStream(string password, 
     Stream in_stream, Stream out_stream, bool encrypt) 
    { 
     // Make an AES service provider. 
     AesCryptoServiceProvider aes_provider = 
      new AesCryptoServiceProvider(); 

     // Find a valid key size for this provider. 
     int key_size_bits = 0; 
     for (int i = 1024; i > 1; i--) 
     { 
      if (aes_provider.ValidKeySize(i)) 
      { 
       key_size_bits = i; 
       break; 
      } 
     } 
     //Debug.Assert(key_size_bits > 0); 
     // Console.WriteLine("Key size: " + key_size_bits); 

     // Get the block size for this provider. 
     int block_size_bits = aes_provider.BlockSize; 

     // Generate the key and initialization vector. 
     byte[] key = null; 
     byte[] iv = null; 
     byte[] salt = { 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 
    0xF1, 0xF0, 0xEE, 0x21, 0x22, 0x45 }; 
     MakeKeyAndIV(password, salt, key_size_bits, block_size_bits, 
      out key, out iv); 

     // Make the encryptor or decryptor. 
     ICryptoTransform crypto_transform; 
     if (encrypt) 
     { 
      crypto_transform = aes_provider.CreateEncryptor(key, iv); 
     } 
     else 
     { 
      crypto_transform = aes_provider.CreateDecryptor(key, iv); 
     } 

     // Attach a crypto stream to the output stream. 
     // Closing crypto_stream sometimes throws an 
     // exception if the decryption didn't work 
     // (e.g. if we use the wrong password). 
     try 
     { 
      using (CryptoStream crypto_stream = 
       new CryptoStream(out_stream, crypto_transform, 
        CryptoStreamMode.Write)) 
      { 
       // Encrypt or decrypt the file. 
       const int block_size = 1024; 
       byte[] buffer = new byte[block_size]; 
       int bytes_read; 
       while (true) 
       { 
        // Read some bytes. 
        bytes_read = in_stream.Read(buffer, 0, block_size); 
        if (bytes_read == 0) break; 

        // Write the bytes into the CryptoStream. 
        crypto_stream.Write(buffer, 0, bytes_read); 
       } 
      } // using crypto_stream 
     } 
     catch 
     { 
     } 

     crypto_transform.Dispose(); 
    } 
    // Use the password to generate key bytes. 
    private static void MakeKeyAndIV(string password, byte[] salt, 
     int key_size_bits, int block_size_bits, 
     out byte[] key, out byte[] iv) 
    { 
     Rfc2898DeriveBytes derive_bytes = 
      new Rfc2898DeriveBytes(password, salt, 1000); 

     key = derive_bytes.GetBytes(key_size_bits/8); 
     iv = derive_bytes.GetBytes(block_size_bits/8); 
    } 

を次のように私は抽出後、それを分割しようが、私は再び新しいキーを取得することはできませんし、私は私が間違ってやっているかわからないbytestobehiddenを構築します。

+0

OK、どのように私は 'bytestobehidden'を抽出した後に分割するのですか? –

+0

このバイトをイメージに添付して抽出をどのように読み込むのか、それを理解する例を教えてください。 –

+0

'output'は暗号化されたファイルの暗号化後のパスです。これは私が使用する 'combine()'関数です。 –

答えて

0

bytestobehiddenの先頭に数バイトを追加できます。これはストリームを分割する場所を示します。たとえば、

fileContainer = ... 
RSAcipher = ... 

byte[] header = new byte[3]; 
int fileLength = fileContainer.Length; 
header[0] = (byte) ((fileLength >> 16) & 0xff); 
header[1] = (byte) ((fileLength >> 8) & 0xff); 
header[2] = (byte) (fileLength & 0xff); 

byte[] bytestobehidden = Combine(header, fileContainer, RSAcipher); 

Combine()に3バイトの配列を受け入れるように変更します。あなたの秘密を抽出した後、あなたはその後、

int fileLength = (int) (bytestobehidden[0] << 16) + 
       (int) (bytestobehidden[1] << 8) + 
       (int) bytestobehidden[2]; 

byte[] fileContainer = new byte[fileLength]; 
byte[] RSACipher = new byte[bytestobehidden.Length-fileLength-3]; 
System.Array.Copy(bytestobehidden, 3, fileContainer, 0, fileLength); 
System.Array.Copy(bytestobehidden, fileLength+3, RSACipher, 0, bytestobehidden.Length-fileLength-3); 

&>><<bitwise operatorsあるんすることができます。ヘッダーを2バイトだけ変更することはできますが、64 KBを超えるファイルサイズを扱わないようにする必要があります。一方、3バイトは最大16 MBのサイズにエンコードすることができますが、これで十分です。

+0

ありがとう、このコードは私のコードを編集してme.iのために便利ですし、私は1つのデバッグで暗号化と復号化を行うときにうまく動作しますが、私は暗号化をした後に私のアプリケーションを閉じて、 'RSAdecryption()'からの出力がヌルであるということについて私に再び同じエラーを与えてください。 –

+0

これはプロジェクトのフォローアップの問題であるかもしれませんが、物事のスキームでは、抽出されたバイトストリームを分割して分割することに関連する質問とは別の問題です。関連するコードを示す新しい質問をすることをお勧めします。状況に役立つと思われる場合は、この質問にリンクしてください。 – Reti43

関連する問題