LSBステガノグラフィー

むかしむかし、ハブに最初の投稿を書いた そして、その投稿は非常に興味深い問題、すなわちステガノグラフィーに捧げられました。 もちろん、その古いトピックで提案された解決策は、言葉の真の意味でステガノグラフィーとは言えません。 これは単なるファイル形式のゲームですが、それでもかなり面白いゲームです。



今日は、もう少し深く掘り下げて、LSBアルゴリズムを検討してみます。 興味があれば、猫を歓迎します。 (猫の通行中:約1メガバイト)



まず、簡単な紹介をする必要があります。 暗号化の目的は、機密情報を読み取れないようにすることであることを誰もが知っています。 もちろん、暗号化には独自の応用分野がありますが、データ保護には別のアプローチがあります。 あなたは情報を暗号化することはできませんが、私たちはそれを持っていないふりをします。 ステガノグラフィーが発明されたのはこのためです。 ウィキペディアは、「ステガノグラフィ(ギリシャ語から。Στεγανοσ-ギリシア語。Γραφω-私が書いた、文字通り「秘密の書き方」)は、伝達の事実そのものを秘密にしておくことによる情報の隠された伝達の科学であることを保証します。



もちろん、暗号化方式とステガノグラフィ方式の組み合わせを禁止する人はいません。 さらに、実際にはそうしますが、私たちの仕事は基本を理解することです。 Wikipediaの記事を注意深く調べると、ステガノグラフィアルゴリズムにいわゆる機能が表示されていることがわかります。 コンテナとメッセージ。 コンテナとは、秘密のメッセージを隠すのに役立つ情報です。



この場合、コンテナはBMP形式の画像になります。 まず、このファイルの構造を検討します。 ファイルは、ファイルヘッダー、画像ヘッダー、パレット、画像自体の4つの部分に条件付きで分割できます。 この目的のために、ヘッダーに何が書かれているかを知るだけで済みます。



ヘッダーの最初の2バイトはBM署名です。ダブルワードにはファイルサイズがバイト単位で含まれ、次の4バイトは予約済みでゼロが含まれている必要があります。最後に、ファイルの先頭からイメージバイトまでのオフセットが別のダブルワードに書き込まれます。 24ビットbmpファイルでは、各ピクセルは3バイトのBGRでエンコードされます。



これで画像に到達する方法がわかりましたが、必要な情報をそこに記録する方法を理解する必要があります。 これには、LSBメソッドが役立ちます。 メソッドの本質は次のとおりです。カラーコーディングを担当するバイト単位の最下位ビットを置き換えます。 シークレットメッセージの次のバイトが11001011で、イメージ内のバイトが... 11101100 01001110 01111100 0101100111 ...である場合、エンコードは次のようになります。 シークレットメッセージのバイトを4つの2ビット部分(11、00、10、11)に分割し、イメージの下位ビットを受信したフラグメントで置き換えます:... 111011 11 010011 0 0 011111 1 0 0101100111 ... このような交換は一般に人間の目には見えません。 さらに、多くの古い出力デバイスでは、このような小さな変更を表示することさえできません。



最下位2ビットだけでなく、任意の数のビットを変更できることは明らかです。 次のパターンがあります。変更するビットが多くなるほど、非表示にできる情報が多くなり、元の画像の干渉が大きくなります。 たとえば、次の2つの画像があります。



画像

画像



私はすべての欲望で、それらの違いを見ることはできませんでしたが、2番目の画像では、前述の方法を使用して、ルイスキャロルの詩「The Hunt for the Snark」が隠されています。 ここまで読んでいただければ、おそらく実装について学ぶことに興味があるでしょう。 それは非常に簡単ですが、すぐにすべてがDelphiで行われることを警告します。 これには2つの理由があります。1。Delphiは良い言語だと思います。 2.このプログラムは、マシンビジョンの基礎に関するコースを準備する過程で生まれました。このコースを読んだ人は、Delphi以外は何も知りません。 構文に慣れていない人にとって、明確にするべきことの1つは、shl x-xによるビット単位の左シフト、shr x-xによるビット単位の右シフトです。



文字列に格納されているテキストをコンテナに書き込み、下位2バイトを置き換えると信じています。

書くためのコード:



for i = 1 to length str do

始める

l1 = byte str [ i ] shr 6 ;

l2 = byte str [ i ] shl 2 ; l2 = l2 shr 6 ;

l3 = byte str [ i ] shl 4 ; l3 = l3 shr 6 ;

l4 = byte str [ i ] shl 6 ; l4 = l4 shr 6 ;



f ReadBuffer tmp 1 ;

f 位置 = f 位置 -1 ;

tmp = tmp shr 2 shl 2 + l1 ;

f WriteBuffer tmp 1 ;



f ReadBuffer tmp 1 ;

f 位置 = f 位置 -1 ;

tmp = tmp shr 2 shl 2 + l2 ;

f WriteBuffer tmp 1 ;



f ReadBuffer tmp 1 ;

f 位置 = f 位置 -1 ;

tmp = tmp shr 2 shl 2 + l3 ;

f WriteBuffer tmp 1 ;



f ReadBuffer tmp 1 ;

f 位置 = f 位置 -1 ;

tmp = tmp shr 2 shl 2 + l4 ;

f WriteBuffer tmp 1 ;



終わり ;


読み取り用コード:

for i = 1 から MsgSize do

始める

f ReadBuffer tmp 1 ;

l1 = tmp shl 6 ;

f ReadBuffer tmp 1 ;

l2 = tmp shl 6 ; l2 = l2 shr 2 ;

f ReadBuffer tmp 1 ;

l3 = tmp shl 6 ; l3 = l3 shr 4 ;

f ReadBuffer tmp 1 ;

l4 = tmp shl 6 ; l4 = l4 shr 6 ;

str = str + char l1 + l2 + l3 + l4 ;

終わり ;




まあ、非常に怠け者のために- プログラムとそのソースコードへのリンク



ありがとう



All Articles