BMP 影象資訊隱藏及檢測
原理簡介
針對檔案結構的資訊隱藏方法需詳細掌握檔案的格式,利用檔案結構塊之間的關係或根據塊資料和塊大小之間的關係來隱藏資訊。
BMP(Bitmap-File)圖形檔案是 Windows 採用的常見圖形檔案格式,要利用 BMP 點陣圖進行資訊隱藏首先需要詳細瞭解 BMP 檔案的格式,BMP 影象檔案結構比較單一而且固定,BMP 影象由檔案頭、資訊頭、調色盤區和資料區四個部分組成,而 24 位真彩色影象中沒有調色盤資訊。24 位真彩色 BMP 點陣圖檔案包括 3 部分。 第一部分是 BMP 檔案頭。前 2 個位元組是“BM”,是用於識別 BMP檔案的標誌;第 3、4、5、6 位元組存放的是點陣圖檔案的大小,以位元組為單位;第7、8、9、10 位元組是保留的,必須為 0;第 11、12、13、14 位元組給出點陣圖陣列相對於檔案頭的偏移,在 24 位真彩色影象中,這個值固定為 54;19,20,21,22表示的是影象檔案的寬度,以畫素為單位;23,24,25,26 表示的是影象檔案的高度,以畫素為單位。第二部分是點陣圖資訊頭。從第 29 個位元組開始,第 29、30 位元組描述的是畫素的位數, 24 位真彩色點陣圖。該位的值為 0x18; 第三部分是資料區。從第 55 個位元組開始,每 3 個位元組表示一個畫素,這 3 個位元組依次表示該畫素的紅、綠、藍亮度分量值。
在不影響影象正常顯示情況下,可使用以下四種方法在 24 位真彩色 BMP 影象中隱藏資訊。
- 在影象檔案尾部新增任意長度的資料,祕密資訊存放在檔案尾部可以減少修改檔案頭的資料量,僅需修改檔案頭中檔案長度的值即可。
- 在調色盤或者點陣圖資訊頭和實際的影象資料之間隱藏資料,如果將祕密資料放在檔案頭與影象資料之間,則至少需要修改檔案頭中檔案長度、資料起始偏移地址這兩個域的值。
- 修改檔案頭和資訊頭中的保留欄位隱藏資訊。
- 在影象畫素區利用影象寬度位元組必須是 4 的倍數的特點,在補足位處隱藏資料。
操作環境
Windows 10 作業系統
MATLAB 2019a 版本軟體
BMP 格式圖片檔案
010 編輯工具
技術過程
一、在實際的影象資料後隱藏資訊
待隱藏的祕密資訊檔名稱為 hidden.txt, Baboon.bmp 為載體影象,將載體和祕密資訊放置在同一個目錄下,在 Windows 的 MS-DOS 方式下執行命令 Copy baboon.bmp /b + hidden.txt /a baboon1.bmp ,其中引數/b 指定以二進位制格式複製、合併檔案,引數/a 以 ASCII 格式複製、合併檔案。執行該命令後,生成一個新的 baboon1.bmp 檔案,使用影象瀏覽工具瀏覽該檔案發現與原始載體影象幾乎完全相同,資訊隱藏在 baboon.bmp 檔案的尾部。從 BMP 影象的結構中可知,影象的 3、4、5、6 四個位元組存放整個 BMP 影象的長度。使用該方法隱藏資訊時,未修改影象檔案的檔案長度位元組,通過比較檔案的實際長度和
檔案中儲存的檔案長度,就可發現該影象是否隱藏祕密資訊。
(1)製作隱藏資訊的圖片QftmModify1.bmp
建立Hidden.txt檔案
製作QftmModify1.bmp
copy Qftm.bmp/b + hidden.txt/a QftmModify1.bmp
(2)Matlab指令碼檢測檔案是否存在隱藏資訊
檢測圖片QftmModify1.bmp檔案長度
clc; clear; fid=fopen('QftmModify1.bmp','r'); %讀入載體影象檔案 [a,length]=fread(fid,inf,'uint8');%length 是檔案的實際長度 fclose(fid); fid=fopen('QftmModify1.bmp','r'); status=fseek(fid,2,'bof'); fileb=fread(fid,4,'uint8'); filelength=fileb(1)*1+fileb(2)*256+fileb(3)*256^2+fileb(4)*256^3 %檔案影象中儲存的檔案長度 diff=length-filelength; %diff 表示隱藏的資訊長度如果相同,表示影象沒有隱藏任何資訊。 fclose(fid);
執行指令碼檢視diff結果
從結果可以看出來當沒有對bmp的檔案標頭檔案長度進行修改時,隱藏的圖片diff差值不等於0,得到圖片存在資訊隱藏。
二、檔案頭與影象資料之間隱藏資訊
在資料區開始之前隱藏資訊,隱藏的祕密資訊從 hidden.txt 檔案中讀取(隱藏整個檔案),此種方法修改影象資料的偏移量和影象資料的檔案長度。
(1)Matlab指令碼進行隱藏資訊
clc; clear; wm=randsrc(1,300, [0 1]); % 產生隨機水印 fid=fopen('Qftm.bmp','r'); %讀入載體影象檔案 [a,length]=fread(fid,inf,'uint8'); fclose(fid); msgfid=fopen('hidden.txt','r');%開啟祕密檔案 [msg,count]=fread(msgfid); fclose(msgfid); wa=a; j=1; wa(11)=54+count; wa(3)=wa(3)+count; for i=55:54+count wa(i)=uint8(msg(j,1));%隱藏密碼資訊 j=j+1; end for i=55:length wa(i+count)=a(i); end figure; wa=uint8(wa); fid=fopen('watermarked.bmp', 'wb'); fwrite(fid,wa); fclose(fid); I=imread('Qftm.bmp'); J=imread('watermarked.bmp'); subplot(1,2,1) imshow(I) title('未修改影象'); subplot(1,2,2) imshow(J) title('修改後影象')
執行結果檢視
分析《watermarked.bmp》16進位制清晰檢視隱藏效果
三、BMP 影象檔案隱藏資訊的檢測
在BMP影象中隱藏資訊的時候一般都是通過修改檔案的偏移量和影象檔案中影象的長度來隱藏資訊,但在BMP影象檔案中,file_length=biwidth*biBytecount*biHeight+bfoffBits,其中 biwidth,biheight表示
影象檔案的寬度和高度,bfoffBits表示檔案頭到實際點陣圖影象資料之間的偏移量。
(1)Matlab指令碼對Bmp進行資訊隱藏多層Check
clc; clear; wm=randsrc(1,300, [0 1]); % 產生隨機水印資訊 fid=fopen('watermarked.bmp','r'); %讀入載體影象檔案 [a,length]=fread(fid,inf,'uint8'); status=fseek(fid,2,'bof'); fileb=fread(fid,4,'uint8'); filelength=fileb(1)*1+fileb(2)*256+fileb(3)*256^2+fileb(4)*256^3 %檔案影象的理論長度 status=fseek(fid,10,'bof'); b=fread(fid,4,'uint8'); bfoffbitsmodify=b(1)*1+b(2)*256+b(3)*256^2+b(4)*256^3 %讀取偏移量 status=fseek(fid,18,'bof'); b=fread(fid,4,'uint8'); biwidth=b(1)*1+b(2)*256+b(3)*256^2+b(4)*256^3 status=fseek(fid,22,'bof'); b=fread(fid,4,'uint8'); biHeight=b(1)*1+b(2)*256+b(3)*256^2+b(4)*256^3; bfoffbits=54;%偏移量 biBytecount=3;%24 位真彩色影象為 3 filetruelength=biwidth*biBytecount*biHeight+bfoffbits %圖片實際真實長度(固定偏移54) filelengthbfoffbits=biwidth*biBytecount*biHeight+bfoffbitsmodify %讀取偏移計算檔案長度 fclose(fid); diff1=length-filelength; %未修改圖片長度時Check1 diff2=filelength-filetruelength %修改了圖片長度時Check2 diff3=filelengthbfoffbits-filetruelength %修改了圖片偏移時Check3 diff=diff1+diff2+diff3
對watermarked.bmp(檔案長度和檔案偏移都被修改了)進行測試,根據diff的值進行判定該圖片是否存在資訊隱藏,執行結果檢視:
從結果diff != 0可以看出來該圖片存在資訊隱藏。
四、在影象檔案頭和資訊頭的保留欄位中隱藏資訊
BMP 影象檔案中有很多從不使用的保留位元組,如 7、8、9、10 位元組是保留的,必須為 0,可在第 7、8、9、10 位元組隱藏祕密資訊。
(1)Matlab指令碼對Bmp的保留欄位隱藏資訊
clc; clear; fid=fopen('Qftm.bmp','r'); %讀入載體影象檔案 [a,length]=fread(fid,inf,'uint8'); fclose(fid); wa=a; % 在BMP的7、8、9、10保留字中隱藏祕密資訊Qftm,ASCII值為0x51 0x66 0x74 0x6d wa(7)=81; wa(8)=102; wa(9)=116; wa(10)=109; figure; wa=uint8(wa); fid=fopen('watermarkedReserve.bmp', 'wb'); fwrite(fid,wa); fclose(fid); I=imread('Qftm.bmp'); J=imread('watermarkedReserve.bmp'); subplot(1,2,1) imshow(I) title('未修改影象'); subplot(1,2,2) imshow(J) title('修改後影象')
分析《watermarkedReserve.bmp》16進位制清晰檢視隱藏效果
&n