一个非常简单的部分位图加密解决方案
一种简单快速的图像加密技术,方便在常用应用程序中安全地使用外部图像文件。
问题描述
对于开发者来说,将应用程序图像存储在单独的图像文件中通常是更可取的,因为这使得应用程序的构建和维护更加容易。例如,使用外部图像通常有助于程序员和 GUI 设计师之间的合作,适应本地化和主题的使用,并且使更新过程更容易和更快。
另一方面,拥有单独的图像文件使得未经授权的人员更容易更改应用程序的外观,这通常是不可接受的。有人可能会补充说,在外部图像文件的情况下,也存在窃取 GUI 图像的风险。在我看来,这不是一个重要的问题(至少对于静态图像而言),因为这些图像最终将被显示在屏幕上,并且屏幕截图非常容易。因此,几乎不可能避免窃取 GUI 图像。
提出的解决方案和基本设计决策
为了使用外部图像并避免上述危险,最明显的解决方案是对图像数据进行加密。但是,加密会给图像加载过程带来两个新问题。它将使这个过程更加复杂和缓慢。由于*加载速度*和*简洁性*在我的情况下非常重要,所以我做出了以下设计决策
- 我选择了一种相对快速且简单的对称加密算法:BlowFish [1,2] 算法。
- 我决定实际上只加密部分图像数据。即,每个图像的前
N
个连续像素行将被加密,接下来的M
个像素行将不被加密,然后再次接下来的N
个像素行将被加密等等。N
和M
的实际值将由用户定义。 - 由于之前的设计决策(#2),此解决方案只能轻松地与未压缩的图像一起使用。此外,目前,我仅针对 DIB Sections 实现了它,因为我个人大部分时间都在使用未压缩的 BMP。
由于上述设计决策,加密的图像将很容易识别(只有一些像素行将被加密),但是很难在另一个应用程序中重用它,甚至更难以在现有应用程序中替换或修改它。
代码实现和用法
我所有的实现代码都位于 CImgCrypt
类中,该类派生自 George Anescu 在另一篇 CodeProject 文章 [1] 中引入的 CBlowFish
类。与 CBlowFish
类相比,CImgCrypt
提供了两个额外的公共方法,可用于加密和解密 DIB Sections。
bool CImgCrypt::EncryptDIBSection(HBITMAP hbitmap, unsigned encryptedHeight, unsigned unencryptedHeight) bool CImgCrypt::DecryptDIBSection(HBITMAP hbitmap, unsigned encryptedHeight, unsigned unencryptedHeight)
具体来说,CImgCrypt::EncryptDIBSection
和 CImgCrypt::DecryptDIBSection
方法分别加密或解密与它们的 hbitmap
参数相对应的 DIB Sections,轮流处理 encryptedHeight
像素行,并跳过 unencryptedHeight
像素行。这两个方法在成功时都返回 true
,否则返回 false
。作为一个简单的用法示例,我在下面演示了一段加载和解密 BMP 文件的代码
CImgCrypt imgCryptEngine("blowfish-key", 12); HBITMAP hBitmap = (HBITMAP)LoadImage(NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); imgCryptEngine.DecryptDIBSection(hBitmap, 3, 6);
我希望这项工作对您有所帮助。在下载部分,您还会找到一个演示应用程序,该应用程序提供了对我在本文中描述的内容的更“实时”的演示。感谢您阅读本文。
致谢
我基于 George Anescu [1] 的 BlowFish 实现完成了这项工作,并且还在我的演示应用程序中使用了 Chris Maunder [3] 的 CDIBSectionLite
类。非常感谢大家!
未来计划
- 基准测试许多 Blowfish 实现,然后使用更快的那个。
- 扩展这项工作,使其也适用于除了未压缩的 BMP 之外的其他图像格式。
历史
- 2006 年 3 月 16 日
- 初始发布。