上周末給大家培訓了lsb隱寫,但由于時間倉促,講得可能過快,導致部分同學未能領悟,故作此文,以幫助各位同學們領悟!
- 首先,給大家講講什么叫位圖
我們不妨把冠希的照片放大看看
放大后可以注意到,這個圖片其實是由一個個不同顏色的格子從左到右從上到下排列組成的,對,就是如此多不同顏色的格子這樣排列組成了這張好看圖片!這就叫位圖!
什么?你覺得我給你的這個解釋太粗糙?那我來點比較學術的解釋(已經知道什么叫位圖的同學可以略過):
- 那么現在我們來說,假如我現在有一串資訊
比如說這么一串"JUST{Guan_xi_ge}"
這串資訊我們想要隱藏進冠希的這個照片,這樣我們想要傳遞給別人的資訊可以以圖片為載體傳給別人,即便被某個壞人截獲了他也很難知道我們真的要傳遞的資訊是什么,因為我們要傳遞的資訊已經被隱藏或者說被隱寫進了這個圖片!!
- 那么,怎么隱寫呢?
這次給大家講解的隱寫方式便是LSB(最低有效位)隱寫,
在前文中,我們已經介紹了位圖,而LSB隱寫便是專門針對這種格式的圖片的一種隱寫方式,
前文中說到位圖是由一個個密密麻麻的各種顏色的小方格一行一行的排列而成的精美圖片,
這個小方格,我們稱其為"像素點",
而這些像素點的顏色各種各樣才能組成我們眼前這副彩色的圖,那么我們的計算機是怎么識別變化每個像素點的顏色的呢?
大家應該都知道紅(R)、綠(G)、藍(B)三元色吧,通過調配這三種顏色,我們可以得到所有的顏色,而在計算機中,每個像素點的顏色便是通過調配其R、G、B的所占成分(值)從而得到的,也就是說,每個顏色的像素點,在計算機看來其實都是一組R、G、B的值,
如下圖,我們選中白色,識別出其R、G、B的值分別為255、255、255,在計算機看來,R、G、B這三種顏色中每個顏色對應的值都是一個8位二進制數,因此,在計算機讀入時,實際上這三元色的值分別為11111111,11111111,11111111,所以,對于計算機而言,它看到的這么一個像素點實際上就是11111111 11111111 11111111這么一個二進制串,我們稱其為該像素點的RGB碼(二進制),為了方便人閱讀,我們人常常將這串二進制串寫作十六進制形式,也就是#ffffff,這也是這個像素點的RGB碼(十六進制),
既然對于計算機而言,每個這樣的像素點是一串二進制串(如:11111111 11111111 11111111),而我們在前文中已經說到一張位圖是由一行一行密密麻麻排列的像素點構成的,那么這么一張圖,不就正是一行一行的二進制串嘛!(示意圖如下)
那么我們怎么把"JUST{Guan_xi_ge}"隱寫進去呢?
我們知道,在計算機中,每個字符實際上是用ascii碼表示的,那我們現在把每位字符轉換成其對應的八位二進制ascii碼形式即可得到該字串是這樣的一串二進制串:
01001010 01010101 01010011 01010100 01111011 01000111 01110101 01100001 01101110 01011111 01111000 01101001 01011111 01100111 01100101 01111101
把我們要隱寫的資訊轉換成這么一串二進制串后,我們就開始隱寫進這個圖片!!!!隱寫,正式開始!!!
現在我們將剛剛轉換成的二進制串的每個二進制位從左至右依次寫入上文中所說的圖片的每八位二進制的最低位(也就是依次寫入圖片像素點R、G、B值的最低位)
例如:
按這樣寫入后,資訊的每一位就被我們隱藏進了像素點的R、G、B對應的8位二進制碼的末位(最低位),因此這種隱寫方式被我們稱作"LSB(最低有效位)隱寫"
我們寫入資訊之后,也看不出圖片有多大的變化,為什么呢?前面已經說了,在計算機中,每個像素點的顏色便是通過調配其R、G、B的所占成分(值)從而得到的,那按我們這種隱寫方式,資訊寫入R、G、B的最低位,如果R、G、B的最低位因為我們的寫入產生變化了,無非也就是1變成了0或者0變成了1,從數值上來講,被我們隱寫過的R、G、B值,最多也就會變化1,這樣對每個像素點說,其R、G、B成分的變化是十分微小的,顏色幾乎沒變,所以人的肉眼是難以察覺到這樣的變化的,因此資訊才得以悄聲無息地被我們藏進去!
以下是由python實作的將資訊隱藏進guanxi.bmp這副圖的python代碼實作(注釋對重要功能的代碼進行了說明,想習得具體函式細節可自行百度(百度:python XXX函式),"XXX"為你未看懂的函式的名字,一定能搜到的!):
from PIL import Image
# 定義函式getflag將要隱寫的文本的內容轉換成其對應的二進制串
def getflag(path): # 以二進制檔案形式打開檔案 f = open(path, "rb") # 讀入檔案內容 s = f.read() # 將檔案內容轉換成其對應的二進制碼 str0 = "" for i in range(len(s)): str0 = str0+(bin(s[i]).replace("0b", "")).zfill(8) f.closed return str0
# 定義函式對圖片進行隱寫 def get(impath, txtpath, newpath): flag = getflag(txtpath) flen = len(flag) # 打開圖片 im = Image.open(impath) # 讀入寬和高 w = im.size[0] h = im.size[1] print("width:"+str(w)) print("height:"+str(h)) cnt = 0 # 將資訊逐位隱寫進圖片 for h in range(h): for w in range(w): pix = im.getpixel((w,h)) r = pix[0] g = pix[1] b = pix[2] if cnt == flen: break r = r - r % 2 + int(flag[cnt]) cnt = cnt + 1
if cnt == flen: im.putpixel((w,h),(r,g,b)) break
g = g - g%2 + int(flag[cnt]) cnt = cnt + 1
if cnt == flen: im.putpixel((w,h),(r,g,b)) break
b = b - b%2 + int(flag[cnt]) cnt = cnt + 1 if cnt == flen: im.putpixel((w, h), (r, g, b)) break
if cnt % 3 == 0: im.putpixel((w, h),(r, g, b)) # 保存隱寫后的圖片到相應路徑 im.save(newpath)
# 開始隱寫 impath = "E:\ctf\guanxi.bmp" txtpath = "E:\ctf\\flag.txt" newpath = "E:\ctf\guanxige.bmp" get(impath, txtpath, newpath) |
- 收到這樣一幅隱寫著資訊的圖,你該怎么將其資訊提取出來呢?
前文已經說了,我們的資訊的二進制串被寫進了圖片中像素點的R、G、B的最低位,那么我們要讀取資訊,便首先要將圖片每個像素點的R、G、B的最低位提取出來,即可得到原來資訊對應的二進制串,在前文中我們已經說了,資訊的每個字符對應著一個8位二進制碼,所以我們就八位八位地讀取這個資訊對應的二進制串,將其逐個轉化為字符,即可得到被藏進去的資訊,
- 那么現在我們來實作將隱寫進圖片資訊提取出來這一操作
這里介紹一個圖片隱寫分析工具叫stegsolve,接下來我們就用它來提取出lsb隱寫過的圖片的資訊,
運行stegsolve需要先安裝java環境,java環境的安裝和配置教程如下(雙擊即可點開,你也可以拖到桌面或電腦里其它位置):
<<java環境配置說明(供運行stegsolve圖片隱寫分析工具用).pdf>>
同時下載好stegsolve(工具在此,雙擊即可點開,你也可以拖到桌面或電腦里其它位置):
<<Stegsolve.jar>>
運行stegsolve
然后點擊"File",再點擊"Open",找到我們被隱寫后的圖片
選中,然后"打開"
現在開始提取資訊
點擊"Analyse",而后點擊"Data Extract",即可進入圖片位提取的工具頁面
前面我們已經說了,要讀取資訊,便首先要將圖片每個像素點的R、G、B的最低位提取出來,即可得到原來資訊對應的二進制串,我們可以看到工具界面中,Red、Green、Blue各有8位選項,即你要提取圖片像素點的R、G、B的哪一位,我們要提取的是它們的最低位,因此都勾選0,
點擊preview,該工具就會把每個像素點的R、G、B的最低位提取出來,并八位八位地進行讀取,即可得到我們藏在圖中的資訊(如下圖)
以下是由python實作的將隱藏進圖片的資訊提取出來的python代碼實作(注釋對重要功能的代碼進行了說明,想習得具體函式細節可自行百度(百度:python XXX函式),"XXX"為你未看懂的函式的名字,一定能搜到的!):
# coding=utf-8
from PIL import Image
# 定義get函式,用于讀取被lsb隱寫后的圖片中的隱寫的資訊 def get(impath): # 打開圖片 im = Image.open(impath) # 讀入寬和高 w = im.size[0] h = im.size[1] print("width:"+str(w)) print("height:"+str(h)) str0 = "" # 提取每個像素的最低位 for h in range(h): for w in range(w): # 提取對應位置處的像素點,并將其r、g、b的值分別賦值給r、g、b pix = im.getpixel((w,h)) r = pix[0] g = pix[1] b = pix[2] # 提取出r、g、b的最低位并依次放入str0中 str0 = str0 + str(r % 2) + str(g % 2) + str(b % 2) # 每八位作為一個二進制ascii碼,將其對應的字符讀取出來 for i in range(0,len(str0),8): print(chr(int(str0[i:i+8],2)), end = "")
# 開始隱寫 impath = "E:\ctf\guanxige.bmp"
get(impath) |
- 看到這里,我想你一定懂怎么進行LSB隱寫了吧,試試對這張照片進行隱寫和解開隱寫吧!!!第一個搞完并把程序和結果截圖發給我的人,獎勵一杯奶茶!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/196061.html
標籤:其他
上一篇:lsb隱寫詳講
下一篇:lsb隱寫詳講
