视觉密码学演示 / Visual Cryptography

作者:Suanovil (Sue)
用纯物理叠加(黑覆盖白)就能"解密"图像——无需任何计算。

原图(二值化)

黑色=要隐藏的内容
先上传图片

叠加结果 S1 + S2

两张 share 物理叠加 → 可见原图
生成后显示

Share 1

单独看是纯噪声

Share 2

单独看也是纯噪声
名字由来——"2-out-of-2" 是什么意思?
这是密码学里"门限方案"的标准记号 (k, n)-threshold:n 张 share 中任意 k 张就能解。所以:
  • (2, 2) = "2-out-of-2":共 2 张,必须凑齐才能解(本 tab)
  • (2, 3) = "2-out-of-3":共 3 张,任意 2 张就能解(多秘密 tab 的变体)
  • (k, n):通用情况,少于 k 张完全无信息
这是 Naor-Shamir 1994 论文里建立的命名。

本 tab 的算法:每个原像素 → 2×2 子像素块。随机选一个"2 黑 2 白"的模式(共 6 种):
• 原像素是:S1、S2 用相同模式 → 叠加 = 2 黑 2 白(50% 灰)
• 原像素是:S1、S2 用互补模式 → 叠加 = 4 个全黑(100% 黑)

因为每个 share 的局部模式是均匀随机的(每像素是 6 种模式之一),单张完全看不出原图——这是 信息论意义上的完美保密(等同于 one-time pad 的强度)。
⚠️ 数字叠加要用 Multiply 混合模式:CMYK share 是减色油墨模型——物理叠加时油墨吸光,相当于 RGB 通道取 MIN。但 Photoshop / Figma 默认是 Normal 混合(上层覆盖下层),叠加效果会错。把上层 share 的混合模式改成 Multiply (正片叠底),结果才对。打印到透明胶片物理叠加就没这个问题(油墨真的会减色)。

原图

CMYK 四通道分别加密(4 套 2-out-of-2)
先上传彩色图

叠加结果 S1 + S2

用 RGB MIN 模拟油墨叠加(减色)→ 还原彩色原图
生成后显示

Share 1

彩色噪声 — CMYK 4 通道随机油墨拼成的"印刷网点"

Share 2

彩色噪声 — 单看也无信息
彩色 CMYK 视觉密码原理:把 RGB 转为 CMYK(Cyan/Magenta/Yellow/blacK 四种油墨)。每个通道独立做 Bayer 抖动 → 二值化的"网点"图(深浅由黑点密度体现)。
对 4 个通道分别跑标准 2-out-of-2 视觉密码,得到 4 对二值 share。把每张 share 的 4 通道按"油墨在 → 该色光被吸收"渲染回 RGB:
R = 255·(1−C)·(1−K), G = 255·(1−M)·(1−K), B = 255·(1−Y)·(1−K)
所以 share 的每个子像素只能是 8 种基色之一:白、青、品红、黄、红、绿、蓝、黑(油墨组合的物理结果)。

叠加用 RGB 通道取 MIN(每个通道取小的那个)—— 等价于"两张透明片重叠后该色光的透过率取小"。这就是真实印刷油墨叠加的物理模型。
原图饱和颜色还原度高,原图白色区域因为 50% 油墨覆盖会看起来偏灰/带轻微色偏,这是 OR 叠加的固有特性。

① 上传三张秘密图(每张对应一对 share 叠加时显形)

S1+S2 秘密 #1

叠加 Share 1 + Share 2 时显形
上传图片

S1+S3 秘密 #2

叠加 Share 1 + Share 3 时显形
上传图片

S2+S3 秘密 #3

叠加 Share 2 + Share 3 时显形
上传图片

② 三张 Share(每张就是均匀网点噪声,单看完全无信息)

Share 1 打印

参与解密:秘密 #1、#2
三张秘密都上传后
自动生成

Share 2 打印

参与解密:秘密 #1、#3
三张秘密都上传后
自动生成

Share 3 打印

参与解密:秘密 #2、#3
三张秘密都上传后
自动生成

③ 三对 Share 的物理叠加预览(OR 模拟)

S1+S2 → 应显出 秘密 #1

三张秘密都上传后
显示叠加

S1+S3 → 应显出 秘密 #2

三张秘密都上传后
显示叠加

S2+S3 → 应显出 秘密 #3

三张秘密都上传后
显示叠加
3-share / 3-secret 半色调 VC(无 cover)原理:
每张 share 默认填入独立的随机 50% 黑白噪声(视觉上像均匀的 TV static / 半色调网点)。
对每个秘密像素 → N×N 子像素块,块内随机抽 6K 个位置分给 3 个 pair:
  • Z₁₂ (2K 子像素):编码秘密 #1。Share 1、2 在这里用 2-of-2 VC pattern;Share 3 保留原随机噪声。
  • Z₁₃ (2K 子像素):编码秘密 #2。Share 1、3 走 VC;Share 2 保留噪声。
  • Z₂₃ (2K 子像素):编码秘密 #3。Share 2、3 走 VC;Share 1 保留噪声。
  • Z_rest (N²−6K):三张 share 全保留随机噪声。
约束:6K ≤ N²

为什么单 share 完全均匀(彻底无泄漏):无论 SEP pattern 还是随机噪声,每个子像素都是 50% 黑 50% 白。所以三张 share 的密度处处恒等于 50%(均匀 TV static),不携带任何秘密相关结构——与 tab 2 那种"share 上能看到 ~15% 密度偏差勾勒出秘密轮廓"的情况彻底不同。

叠加为什么显形秘密:
• Z_ij 区域:SEP 起作用——秘密=白时 K 个子像素黑(50% 灰),秘密=黑时 2K 个全黑(100%)
• 其它区域:两张独立 50% 随机噪声 OR = 75% 灰(背景)
所以叠加图:均匀 75% 灰背景里,秘密的白区呈 50% 灰(亮斑),黑区呈 100% 纯黑(深斑),双向对比都可见。

调参:K 越大单 pair 信号越强(K/N² 对比);N 越大单像素的网点更细腻。N=6, K=3(默认)= 8% 对比;N=4, K=2 = 12.5% 对比(更明显但子像素粗)。

秘密图选图建议:简单高对比的形状最佳(图标、文字、剪影);不要用照片当秘密——细节会被半色调网点淹没。

打印:点 "导出 3 张打印 PNG" 一次性按 mm 尺寸以 300 DPI 透明 PNG 下载 3 张 share。必须一次性导出因为算法依赖共享的随机种子——如果分次导出会得到 3 张互不相干的 share,叠加根本无法解密!
预览 PNG 也是透明底,从当前画布抓取,三张预览只要在同一次生成之后下载也是一致的。

物理打印:胶片 + 激光打印机 → 实际尺寸 100% 打印(不要"自适应页面")→ 角标对齐叠加即可。