Open YIXUNFE opened 8 years ago
大家都知道在信息经过加密算法处理后,我们一般是无法直接从信息中读取内容,而且信息看上去并不那么合理。对于专注信息安全的人,可以从信息的奇怪的外观上判断信息是否经过加密处理,这无疑是此地无银三百两,招着人家来破解你的加密内容。
而今天要介绍的图片隐写则更像是“大隐隐于市”的一种技巧。
图片隐写正是隐写术的一种。隐写术的英文是Steganography,来源于15世纪一个德国修道士特里特米乌斯(Trithemius)写的一本讲述密码学和隐写术的著作《Steganographia》。该书书名源于希腊语,意为“隐秘书写”。
隐写术的使用可以追溯到希腊时代。当时有个人为了能够将机密信息传递给盟友,于是将一个奴隶的头发剃光,然后在头皮上写上内容,等到奴隶的头发长长后就派他去送信。盟友只需要再将这个奴隶的头发剃光即可获得信息。
隐写术不同于密码术,它更为隐蔽。密码术虽然无法让人直接获取到内容,但是在信息的传递过程中可以被一眼辨认出与正常内容的区别。而隐写术可以说是侧重在隐蔽信息的传递过程。
我们来看这张图
好像就是一张平白无奇的纯蓝色的图,是吗?其实这张图片中还隐藏了一张图。在讲述如何破解隐写内容之前,我们先聊聊是如何将另一张图片隐写入原图的。
我们知道一张图片是由许多的像素点组成的。每个像素点包含4个通道,即 R(红)G(绿)B(蓝)A(透明度),我们就从通道上做手脚。
最简单的,由于肉眼无法区分像素值上的细微差距。可能有自称像素眼的同学不信,你有看出下图的颜色区别吗?
既然我们无法区分像素值的细微差别,那么利用这点,我们就可以实现图片隐写术了。
我们看下被隐写的图片:
可以看见这张图中的颜色并不是很丰富,大约只有三种颜色。那么我们通过 PS 取色,可以获得如下三个颜色:
rgba(29, 122, 217, 255) rgba(255, 255, 255, 255) rgba(255, 111, 0, 255)
imageData
然后将原图像素的红通道的个位数拍扁(置 0),这里以 canvas 获取的 imageData 对象为例:
// 循环原图的 imageData.data for (i; i < l; i += 4) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 }
由于取色器获取的颜色与被隐的图像上的颜色会有细微差别,所以设置一个阈值做容差处理。在循环原图像素的同时,获取被隐图像上对应点的像素值,进行比对:
for (i; i < l; i += 4) { if ( Math.abs(simgData[i + 0] - 29) < yu && Math.abs(simgData[i + 1] - 122) < yu && Math.abs(simgData[i + 2] - 217) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 } else if ( Math.abs(simgData[i + 0] - 255) < yu && Math.abs(simgData[i + 1] - 255) < yu && Math.abs(simgData[i + 2] - 255) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 1 } else if ( Math.abs(simgData[i + 0] - 255) < yu && Math.abs(simgData[i + 1] - 111) < yu && Math.abs(simgData[i + 2] - 0) < yu ) { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 2 } else { imgData[i + 0] = (imgData[i + 0] / 10 | 0) * 10 + 3 } }
我们在代码中将被隐图像的颜色对应为原图红通道中的个位数数值:
我们的图片隐写术就这么完成了。最后产生的就是上面看着像纯蓝色的图像。
可以看出,隐写图片的关键是提取被隐图片的颜色值,然后通过一些方法将颜色值放入原图的通道数值中。上面的例子中将红通道的个位数置 0 后,可以隐入 10 中色彩的图片,如果隐入的图片色彩更丰富,可能动用更多的通道,或者通过其他的一些算法达到目的。
接下来的工作就是来进行对被隐图片的提取了。首先将上一部生成的图像数据进行循环,然后取出每个像素的红通道数值。
for (i; i < l; i += 4) { temp = imgData[i + 0] % 10 if (temp === 0) { simgData[i + 0] = 29 simgData[i + 1] = 122 simgData[i + 2] = 217 } else if (temp === 1) { simgData[i + 0] = 255 simgData[i + 1] = 255 simgData[i + 2] = 255 } else if (temp === 2) { simgData[i + 0] = 255 simgData[i + 1] = 111 simgData[i + 2] = 0 } else { simgData[i + 0] = 29 simgData[i + 1] = 122 simgData[i + 2] = 217 } }
最后我们将获得的像素数据展示出来:
好像有点失真,不过没关系,图像中的主要信息并没有丢失,我们可以清晰的看到图像中的字样。
通常我们会将自己产品的图片加上水印,以注明图片来源并避免被他人用于营利性目的。但是由于加上水印后可能会对图片产生副作用。比如遮挡了图片中信息、水印本身的美感等问题,可能会对用户造成一定的心里落差,毕竟这不是用户的原图。
而通过将产品 logo 隐写入原图的方式,就显得更加优雅,即满足了用户对上传图像的期望,又确保了在被其他商业产品盗用图片时的维权手段。
http://www.guokr.com/article/3741/
打个广告:https://github.com/zcyzcy88/Polytor
@zcyzcy88 有点意思
赞
认识图片隐写
大家都知道在信息经过加密算法处理后,我们一般是无法直接从信息中读取内容,而且信息看上去并不那么合理。对于专注信息安全的人,可以从信息的奇怪的外观上判断信息是否经过加密处理,这无疑是此地无银三百两,招着人家来破解你的加密内容。
而今天要介绍的图片隐写则更像是“大隐隐于市”的一种技巧。
隐写术
图片隐写正是隐写术的一种。隐写术的英文是Steganography,来源于15世纪一个德国修道士特里特米乌斯(Trithemius)写的一本讲述密码学和隐写术的著作《Steganographia》。该书书名源于希腊语,意为“隐秘书写”。
隐写术的使用可以追溯到希腊时代。当时有个人为了能够将机密信息传递给盟友,于是将一个奴隶的头发剃光,然后在头皮上写上内容,等到奴隶的头发长长后就派他去送信。盟友只需要再将这个奴隶的头发剃光即可获得信息。
隐写术不同于密码术,它更为隐蔽。密码术虽然无法让人直接获取到内容,但是在信息的传递过程中可以被一眼辨认出与正常内容的区别。而隐写术可以说是侧重在隐蔽信息的传递过程。
图片的隐写
我们来看这张图
有兴趣的同学可以保存图像后面会用到这张图
好像就是一张平白无奇的纯蓝色的图,是吗?其实这张图片中还隐藏了一张图。在讲述如何破解隐写内容之前,我们先聊聊是如何将另一张图片隐写入原图的。
像素通道
我们知道一张图片是由许多的像素点组成的。每个像素点包含4个通道,即 R(红)G(绿)B(蓝)A(透明度),我们就从通道上做手脚。
最简单的,由于肉眼无法区分像素值上的细微差距。可能有自称像素眼的同学不信,你有看出下图的颜色区别吗?
可以下载后用 PS 取色看看
既然我们无法区分像素值的细微差别,那么利用这点,我们就可以实现图片隐写术了。
我们看下被隐写的图片:
logo 大法好
可以看见这张图中的颜色并不是很丰富,大约只有三种颜色。那么我们通过 PS 取色,可以获得如下三个颜色:
PS 里面透明度是 0 -100%, 对应
imageData
中的数值 为 0 到 255然后将原图像素的红通道的个位数拍扁(置 0),这里以 canvas 获取的
imageData
对象为例:由于取色器获取的颜色与被隐的图像上的颜色会有细微差别,所以设置一个阈值做容差处理。在循环原图像素的同时,获取被隐图像上对应点的像素值,进行比对:
我们在代码中将被隐图像的颜色对应为原图红通道中的个位数数值:
我们的图片隐写术就这么完成了。最后产生的就是上面看着像纯蓝色的图像。
可以看出,隐写图片的关键是提取被隐图片的颜色值,然后通过一些方法将颜色值放入原图的通道数值中。上面的例子中将红通道的个位数置 0 后,可以隐入 10 中色彩的图片,如果隐入的图片色彩更丰富,可能动用更多的通道,或者通过其他的一些算法达到目的。
提取被隐图片
接下来的工作就是来进行对被隐图片的提取了。首先将上一部生成的图像数据进行循环,然后取出每个像素的红通道数值。
最后我们将获得的像素数据展示出来:
好像有点失真,不过没关系,图像中的主要信息并没有丢失,我们可以清晰的看到图像中的字样。
商业用途
通常我们会将自己产品的图片加上水印,以注明图片来源并避免被他人用于营利性目的。但是由于加上水印后可能会对图片产生副作用。比如遮挡了图片中信息、水印本身的美感等问题,可能会对用户造成一定的心里落差,毕竟这不是用户的原图。
而通过将产品 logo 隐写入原图的方式,就显得更加优雅,即满足了用户对上传图像的期望,又确保了在被其他商业产品盗用图片时的维权手段。
查看DEMO
参考文章
http://www.guokr.com/article/3741/
Thanks