diff --git a/README.md b/README.md index d256bc9..8636e9e 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ cloacked-pixel ========== +Language: **English** | [简体中文](README_Chinese.md) + Platform independent Python tool to implement LSB image steganography and a basic detection technique. Features: - Encrypt data before insertion. @@ -89,3 +91,8 @@ Notes - It is entirely possible to have images with the mean of LSBs already very close to 0.5. In this case, this method will produce false positives. - More elaborate theoretical methods also exist, mostly based on statistics. However, false positives and false negatives cannot be completely eliminated. +New Additions +------------- + +1. The README file has been updated with a Chinese translation (provided by AI). +2. Full support for Python 3 has been successfully implemented. diff --git a/README_Chinese.md b/README_Chinese.md new file mode 100644 index 0000000..2ef9915 --- /dev/null +++ b/README_Chinese.md @@ -0,0 +1,92 @@ +![logo](images/logo.png) + +cloacked-pixel +========== + +Language: [English](README.md) | **简体中文** + +一个平台无关的Python工具,用于实现LSB(最低有效位)图像隐写术和基本检测技术。特性包括: + + - 在插入前加密数据。 + - 在最低有效位中嵌入数据。 + - 提取隐藏的数据。 + - 对图像进行基础分析以检测最低有效位隐写术。 + +如何使用: + + $ python lsb.py + LSB 隐写术。将文件隐藏在图像的最低有效位中。 + + 使用方法: + lsb.py hide + lsb.py extract + lsb.py analyse + +隐藏 +---- + +所有数据在嵌入图片之前都会被加密。加密是必须的。这样做有两个后果: + + - 有效载荷将会稍微大一些。 + - 加密后的有效载荷将具有高熵,并且类似于随机数据。这就是为什么最低有效位中的0和1的频率应该是相同的——0.5。在很多情况下,真实的图像并不具备这一特性,因此我们可以区分未修改的图像和带有嵌入数据的图像。 + +加密并隐藏一个压缩包: + + $ python lsb.py hide samples/orig.jpg samples/secret.zip p@$5w0rD + [*] Input image size: 640x425 pixels. + [*] Usable payload size: 99.61 KB. + [+] Payload size: 74.636 KB + [+] Encrypted payload size: 74.676 KB + [+] samples/secret.zip embedded successfully! + +原始图像: + +![原始图像](images/orig.jpg) + +包含75k压缩包的图像: + +![嵌入的压缩包](images/stego.jpg) + +提取 +------- + + $ python lsb.py extract samples/orig.jpg-stego.png out p@$5w0rD + [+] Image size: 640x425 pixels. + [+] Written extracted data to out. + + $ file out + out: Zip archive data, at least v1.0 to extract + +检测 +--------- + +一种简单的检测图像最低有效位是否被篡改的方法基于上述观察——被篡改区域内的最低有效位平均值会接近0.5,因为最低有效位含有加密数据,其结构与随机数据相似。为了分析一张图像,我们将它分割成块,并对每个块计算最低有效位的平均值。要分析一个文件,我们使用以下语法: + + $ python lsb.py analyse + +**示例** + +![城堡](images/castle.jpg) + +现在让我们分析原始图像: + + $ python lsb.py analyse castle.jpg + +![原始图像分析](images/analysis-orig.png) + +… 现在分析包含我们有效载荷的图像: + + $ python lsb.py analyse castle.jpg-stego.png + +![隐写图像分析](images/analysis-stego.png) + +注意事项 +----- + + - 完全有可能存在最低有效位均值已经非常接近0.5的图像。在这种情况下,这种方法会产生误报。 + - 还存在更复杂的理论方法,主要基于统计学。然而,无法完全消除误报和漏报。 + +新增 +----- +1. README新增中文翻译(虽然是由AI翻译的) +2. 完美支持了Python3 diff --git a/lsb.py b/lsb.py index f9c3abb..60284ca 100644 --- a/lsb.py +++ b/lsb.py @@ -25,15 +25,15 @@ def decompose(data): # Assemble an array of bits into a binary file def assemble(v): - bytes = "" + bytes = bytearray() length = len(v) - for idx in range(0, len(v)/8): + for idx in range(0, len(v)//8): byte = 0 for i in range(0, 8): if (idx*8+i < length): byte = (byte<<1) + v[idx*8+i] - bytes = bytes + chr(byte) + bytes.append(byte) payload_size = struct.unpack("i", bytes[:4])[0] @@ -53,14 +53,14 @@ def embed(imgFile, payload, password): img = Image.open(imgFile) (width, height) = img.size conv = img.convert("RGBA").getdata() - print "[*] Input image size: %dx%d pixels." % (width, height) + print("[*] Input image size: %dx%d pixels." % (width, height)) max_size = width*height*3.0/8/1024 # max payload size - print "[*] Usable payload size: %.2f KB." % (max_size) + print("[*] Usable payload size: %.2f KB." % (max_size)) f = open(payload, "rb") data = f.read() f.close() - print "[+] Payload size: %.3f KB " % (len(data)/1024.0) + print("[+] Payload size: %.3f KB " % (len(data)/1024.0)) # Encypt cipher = AESCipher(password) @@ -74,9 +74,9 @@ def embed(imgFile, payload, password): v.append(0) payload_size = len(v)/8/1024.0 - print "[+] Encrypted payload size: %.3f KB " % (payload_size) + print("[+] Encrypted payload size: %.3f KB " % (payload_size)) if (payload_size > max_size - 4): - print "[-] Cannot embed. File too large" + print("[-] Cannot embed. File too large") sys.exit() # Create output image @@ -97,7 +97,7 @@ def embed(imgFile, payload, password): steg_img.save(imgFile + "-stego.png", "PNG") - print "[+] %s embedded successfully!" % payload + print("[+] %s embedded successfully!" % payload) # Extract data embedded into LSB of the input file def extract(in_file, out_file, password): @@ -105,7 +105,7 @@ def extract(in_file, out_file, password): img = Image.open(in_file) (width, height) = img.size conv = img.convert("RGBA").getdata() - print "[+] Image size: %dx%d pixels." % (width, height) + print("[+] Image size: %dx%d pixels." % (width, height)) # Extract LSBs v = [] @@ -127,7 +127,7 @@ def extract(in_file, out_file, password): out_f.write(data_dec) out_f.close() - print "[+] Written extracted data to %s." % out_file + print("[+] Written extracted data to %s." % out_file) # Statistical analysis of an image to detect LSB steganography def analyse(in_file): @@ -140,7 +140,7 @@ def analyse(in_file): BS = 100 # Block size img = Image.open(in_file) (width, height) = img.size - print "[+] Image size: %dx%d pixels." % (width, height) + print("[+] Image size: %dx%d pixels." % (width, height)) conv = img.convert("RGBA").getdata() # Extract LSBs @@ -177,11 +177,11 @@ def analyse(in_file): plt.show() def usage(progName): - print "LSB steganogprahy. Hide files within least significant bits of images.\n" - print "Usage:" - print " %s hide " % progName - print " %s extract " % progName - print " %s analyse " % progName + print("LSB steganogprahy. Hide files within least significant bits of images.\n") + print("Usage:") + print(" %s hide " % progName) + print(" %s extract " % progName) + print(" %s analyse " % progName) sys.exit() if __name__ == "__main__": @@ -195,5 +195,4 @@ def usage(progName): elif sys.argv[1] == "analyse": analyse(sys.argv[2]) else: - print "[-] Invalid operation specified" - + print("[-] Invalid operation specified")