图像的隐写术






4.45/5 (49投票s)
2007 年 5 月 14 日
4分钟阅读

182210

36675
使用图像进行加密文本传输
- 下载方案 1 - 20.9 KB
- 下载方案 1 PDF - 20.9 KB
- 下载示例 - 224.1 KB
- 下载示例 TIF - 224.1 KB
- 下载 Stealth - 491.3 KB
- 下载 Stealth 源代码 - 597.3 KB
引言
我们的目标是构建一个能够将加密消息嵌入图像中进行发送和接收的简单应用程序。用户可以选择他们想要的图像,程序必须能够判断该图像是否适合隐藏文本。不允许像素变形或尺寸失真。TIF 图像可能会有轻微的尺寸增加或减少,但我们稍后会讨论这一点。用户可以为他们发送的每条消息设置不同的密码,这样管理员就可以向两个组传输同一张图像,但使用不同的密码和不同的消息。
使用代码
下面,我将嵌入文本到图像中的主过程放在这里。代码的每一步都经过注释
If MsgBox("You are about to encrypt and embed this message :[[
" + TextBox1.Text + " ]] , Shall We Proceed?", MsgBoxStyle.OkCancel,
"Stealth") = MsgBoxResult.Cancel Then Exit Sub
Label2.Text = ""
If RadioButton1.Checked = False And RadioButton2.Checked = False Then
MsgBox("Please select an extention")
Exit Sub
End If
Dim text As String
text = TextBox1.Text.ToString + " "
Dim passw As String = "" input("Enter Password To Protect Your Text", passw)
If passw = "" Then 'err handler for ugly passwords
MsgBox("Error ! You Didn,t Choose Any Password To Protect The Message.")
Exit Sub
ElseIf passw.Length < 4 Then
MsgBox("Error ! Password Is Too Short.")
Exit Sub
End If
Dim amount As Double = text.Length
process_pass_with_tx(passw, text) ' this will encrypt the test by the
' password this is done by generating a string from the password and this
' string is tall enough to perform bit stream xor operation on all chares
' included in the message text that we want to send. we secured the text,
' now we will try hide the encrypted text in the image.
TextBox1.Text = text
If RadioButton1.Checked = True Then GoTo mode2 ''started deferences
between tow modes here
If Me.OpenFileDialog1.ShowDialog = DialogResult.Cancel Then
Exit Sub
Else 'err handler to prevent wrong extensions
Dim infoReader As System.IO.FileInfo
infoReader = My.Computer.FileSystem.GetFileInfo(
Me.OpenFileDialog1.FileName)
If infoReader.Extension.Substring(1, 3).ToLower <> (
RadioButton2.Text.ToLower) Then
MsgBox("Error : Encryption mode requires different extension ")
Exit Sub
End If
LoadNewPict(Me.OpenFileDialog1.FileName) 'display the selected image preview
If PictureBox1.Image.Size.Width < 64 Or PictureBox1.Image.Size.Height <
64 Then
' prevent user from using unproperiate images
MsgBox("Error! Tiny Images Cann,t Be Used In Steganography.")
Exit Sub
End If
Dim w1 As Integer = PictureBox1.Image.Size.Width - 1
Dim w2 As Integer = PictureBox1.Image.Size.Height - 1
Dim possible_size As Double = ((w1 - 7) * (w2 - 7)) / 8 ' 8 bits make one
' char, and avoid edges
If possible_size < amount Then ' determine if the image is not big enough
' for text
MsgBox("This image is not big enough to carry your message",
MsgBoxStyle.Critical)
Exit Sub
End If
End If ' file dialog if
' load accurding to extention
Dim dib, val, reslt As Integer
dib = FreeImage.FreeImage_Load(FreeImage.FREE_IMAGE_FORMAT.FIF_TIFF,
OpenFileDialog1.FileName, 0)
On Error GoTo rongex1
Dim ba As bits_array
ba.Initialize()
Dim sz As Long
Dim sz1, sz2, sz3, sz4 As Byte
Dim t As Double sz = text.Length ' number of chars to encrypt
sz1 = Decimal.Remainder(sz, 100) ' take the lowest 2 digits of it
t = sz / 100 'take the left numbers (all except lowest 2 digits)
sz = Decimal.Truncate(t) ' set size_variable to hold left numbers (all except
' lowest 2 digits)
sz2 = Decimal.Remainder(sz, 100) ' repeat
t = sz / 100
sz = Decimal.Truncate(t)
sz3 = Decimal.Remainder(sz, 100) ' ' repeat
t = sz / 100
sz = Decimal.Truncate(t)
sz4 = Decimal.Remainder(sz, 100) ' will take final 2 digits, now you can
' see: the maximum size of text is ( 99 99 99 99 )
' now we will convert sz1 to bits array and stor it in the first line of the
' picture after it we will do the sz2 and then sz3 and then sz4..
' the coming 4 for loops are used for that
Dim i, j, m
i = 0
j = 1
ba.Initialize()
byte_to_bits(sz1, ba)
For m = 0 To 7 '''''''''''''''''' 1
i = i + 1
FreeImage.FreeImage_GetPixelColor(dib, i, j, val)
' set the lowest bit according to my bit
If odd(val) = True Then
If ba.bits(m) = False Then 'bit is zero
FreeImage.FreeImage_SetPixelColor(dib, i, j, (val + 1))
End If
End If
If odd(val) = False Then
If ba.bits(m) = True Then 'bit is one
FreeImage.FreeImage_SetPixelColor(dib, i, j, (val + 1))
End If
End If
Next m
ba.Initialize()
byte_to_bits(sz2, ba)
For m = 0 To 7 '''''''''''''''''''''' 2
i = i + 1
FreeImage.FreeImage_GetPixelColor(dib, i, j, val)
If odd(val) = True Then
If ba.bits(m) = False Then 'bit is zero
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
If odd(val) = False Then
If ba.bits(m) = True Then 'bit is one
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
Next m
ba.Initialize()
byte_to_bits(sz3, ba)
For m = 0 To 7 '''''''''''''''''''''''''''' 3
i = i + 1
FreeImage.FreeImage_GetPixelColor(dib, i, j, val)
If odd(val) = True Then
If ba.bits(m) = False Then 'bit is zero
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
If odd(val) = False Then
If ba.bits(m) = True Then 'bit is one
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
Next m
ba.Initialize()
byte_to_bits(sz4, ba)
For m = 0 To 7 ''''''''''''''''''''''''''''' 4
i = i + 1
FreeImage.FreeImage_GetPixelColor(dib, i, j, val)
If odd(val) = True Then
If ba.bits(m) = False Then 'bit is zero
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
If odd(val) = False Then
If ba.bits(m) = True Then 'bit is one
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
Next m '''' we have just stored the size of the text
Dim n As Byte
Dim count As Long
count = 0 'i already set size ===>>> first line for size
' Now i will scan the picture from the second line
For j = 2 To PictureBox1.Image.Size.Height Step 1
i = 1
Do While (i + 7) < PictureBox1.Image.Size.Width ' Step 8 ' may use
' freeimage_getdotspermeterx
n = Asc(CChar(text.Substring(count, 1))) ' this give ascii code for
' the every text letter, to reverse it use chr() function
count = count + 1
If count = text.Length Then GoTo out
ba.Initialize()
byte_to_bits(n, ba) '''''''''''
For m = 0 To 7
FreeImage.FreeImage_GetPixelColor(dib, i, j, val)
' change it according to my bit
If odd(val) = True Then
If ba.bits(m) = False Then 'bit is zero
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
If odd(val) = False Then
If ba.bits(m) = True Then 'bit is one
FreeImage.FreeImage_SetPixelColor(dib, i, j, val + 1)
End If
End If
i = i + 1
Next m
i = i + 8
Loop
Next j
out:
Dim fn As String
Dim con As Integer = 0
fn = OpenFileDialog1.FileName + "_stealth.tif"
up1:
If File.Exists(fn) = False Then
FreeImage.FreeImage_Save(FreeImage.FREE_IMAGE_FORMAT.FIF_TIFF,
dib, fn, &H800S)
Else
con = con + 1
MsgBox("FILE: " + fn + " ALREADY EXISTS ,WE WILL CHANGE THE NAME TO " +
OpenFileDialog1.FileName + con.ToString + "_stealth.tif")
fn = OpenFileDialog1.FileName + con.ToString + "_stealth.tif"
GoTo up1
End If
Label2.Text = fn
Exit Sub
mode2: '
' in mode2 we will treat the file with the deferent extension in the same
way, just change the lib calls according to the extension
' to decrypt the message we will reverse what we have done
关注点
您必须将 freeimage.dll 放在与 EXE 相同的路径下才能使其工作。这已经为您完成。输出图像的名称将与输入图像相同,并在末尾加上 "_stealth";如果输出文件已存在,程序将处理这种情况。文本框控件的最大字符数有限制;如果您的文本超出此限制,请尝试将其分开,并为每个部分使用一张图像。有损压缩算法会损坏图像中的加密数据,因此不建议在传输前压缩输出图像。
您可能会注意到某些图像的尺寸发生了一些变化。与总文件大小相比,这种变化很可能被忽略。这可能是因为生成您提供给程序的原始图像的压缩算法与我的 DLL 库中生成输出图像的压缩算法不同,而不是因为嵌入的数据增加了尺寸。证据是:在您运行程序之前,编写一个小型程序并使用我代码中使用的相同函数将您的图像另存为具有相同扩展名的不同名称。假设这个新图像称为 beta。现在运行程序并使用它来嵌入一些文本。看到输出图像了吗?它的尺寸与 beta 图像完全相同。
您可以使用任何您信任的加密算法,例如公钥/私钥、ElGamal 等。我们的隐写术方式独立于图像的比特采样(每像素比特数),但强烈建议与 24 bpp 或更高的图像一起使用。这将保证防止像素变形。大多数网络图像都采样为 24 bpp。
请注意,我的密钥生成方式很弱,因为我只是重复了密钥。如果密钥中的任何字符被发现,那么用它加密的所有消息字符也会被发现。您应该使用良好的函数来生成一个大字符串来进行 XOR,或者使用更好的密码。您也可以通过在应用程序的某个地方使用背景图像来设置版权文本,从而使用此程序进行身份验证。
低位比特(本程序)不适用于 JPEG,因为它们使用有损压缩算法。因此,处理 JPEG 需要额外的工作。您可以获取图像的红/绿/蓝通道并执行相同的操作。您可以使用它来获取直方图近似于水平线的通道,然后像这样将新图像分割成小方块
1 1 1
1 x 1
1 1 1
在中心像素 x,如果得到位 1,则放置一个大于所有邻居的值。如果得到位 0,则放置一个小于所有邻居的值。现在,这里可以容纳数据的可能大小除以 9。这种方法有时可能会导致轻微失真,因为它作用于高位比特。我们只能使用值大于适当阈值的小方块。或者,像这样将图像分割成小方块
X Y
Y X
如果 X 的像素持有相同的值,则该方块代表 1,Y 的像素必须更改为不同的值。如果 Y 的像素持有相同的值,则该方块代表 0,X 的像素必须更改为不同的值。现在当我们接收时,如果 X 的像素和 Y 的像素不同或两者都相同,那么有人动过这张图像,这个比特是无效的。我们可以将此应用于多个通道,因此如果一个通道损坏,我们将使用备份。最后 2 种算法:Alaa Jebran © 2007。
您可能不会惊讶地发现,像 CIA、NSA 等一些大型机构会使用名人网站或色情网站来发送和接收加密消息,这些消息使用的就是类似的技术。
历史
- 2007 年 5 月 14 日 -- 发布原始版本
- 2007 年 6 月 25 日 -- 文章编辑并移至 CodeProject.com 文章库