​探秘 Web 水印技術

来源:https://www.cnblogs.com/88223100/archive/2022/09/13/Exploring-Web-Watermarking-Technology.html
-Advertisement-
Play Games

Web 水印技術在信息安全和版權保護等領域有著廣泛的應用,對防止信息泄露或知識產品被侵犯有重要意義。水印根據可見性可分為可見水印和不可見水印(盲水印),本文將分別予以介紹,帶你探秘 web 水印技術。 ...


 

 

Web 水印技術在信息安全和版權保護等領域有著廣泛的應用,對防止信息泄露或知識產品被侵犯有重要意義。水印根據可見性可分為可見水印和不可見水印(盲水印),本文將分別予以介紹,帶你探秘 web 水印技術。

可見水印

最簡單的水印

一種比較常見的簡單水印場景是給文章、表格加上 logo 水印,用以申明版權。

 

 這裡想要的效果就是一個淺淺的 logo 平鋪展示。實現起來也比較簡單,只需製作一個半透明的 logo 圖片,設為文章或者表格的背景圖片即可。僅需一行 CSS 聲明。

background-image:url("./logo.png");

實現圖片平鋪關鍵的 CSS 屬性是 background-repeat,值為 repeat 時是平鋪,這也是它的預設值,所以可以省略。

全頁面水印

照葫蘆畫瓢,如果要給整個 Web 頁面加上水印,是不是給頁面的 body 元素設置背景圖片平鋪展示就可以了呢?

然而通常並不會這麼處理,因為文章和表格內容多以文本為主,不會明顯遮擋水印,而一個完整的頁面往往還包含很多其他頁面元素,比如圖片、視頻、控制項等等,它們很可能會遮擋住背景圖片,從而影響水印效果。

所以,為了避免被其他元素遮擋,針對頁面的水印一般會使用一個層級比較高且覆蓋整個頁面的元素來承載。

div.watermark{
  position: fixed;
  left:0;
  top:0;
  width: 100vw;
  height: 100vh;
  background-image:url("./logo.png");
  opacity: .5;
  z-index: 3000;
}

這樣一來,其他元素就遮擋不住水印了。不過,這個 div 反過來可能會遮擋頁面其他元素,影響頁面元素操作。還需要一條關鍵的 CSS 聲明來破解這個問題 :

pointer-events: none;

這個 CSS 聲明會使該元素“可穿透”,“看得見、摸不著”,不再影響頁面操作。

動態水印

很多時候,給頁面加水印的目的並不是申明版權,而是為了支持溯源。此時水印的內容並不會只是一個 logo,通常會包含用戶信息,比如用戶名、UID、手機號等等。

 

 

這就意味著,每個用戶的水印內容是不同的,無法通過提前準備好一張圖片來滿足了。這種場景往往需要根據用戶信息動態生成圖片。

我們來看下幾種主流的動態生成水印圖片的方式:

服務端方案

傳統的方式是在服務端生成圖片。頁面上發起的圖片請求中可以附帶用戶信息,服務端根據這些參數動態生成圖片,並將圖片數據作為該請求的響應返給頁面,頁面拿到後將其用作水印。

這種方式的優點是相容性好,缺點是需要前後端配合,增加了頁面請求和服務端資源開銷,防攻擊能力也較差。

Canvas 方案

HTML5 引入 Canvas 特性使得瀏覽器自身具備了繪圖能力。經過多年的發展,主流瀏覽器基本都已可以提供良好的支持。通過 Canvas 可以輕鬆繪製圖片,並可將圖片數據導出,用於頁面圖片或背景。

const canvasElement = document.createElement('canvas');
const context = canvasElement.getContext('2d');
canvasElement.width = 200;
canvasElement.height = 200;
context.rotate((-30 * Math.PI) / 180);
context.font = '400 26px Arial';
context.fillStyle = '#B9C0CA';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('水印文字', 70, 130);
const watermark = canvasElement.toDataURL('image/png');

通過上述示例代碼可拿到水印圖片的 data URI 數據,用作水印承載元素的背景圖片平鋪展示即可。

這種方式不需要服務端配合,在前端就可以完成,且有助於減少請求和服務端資源開銷。曾經面臨的瀏覽器相容問題現在也不再是問題,該方案已逐漸流行起來。

SVG 方案

對於純文字的水印來說,有沒有辦法不生成圖片而直接實現平鋪呢?

動態創建大量 DOM 節點,通過 CSS 控制排列當然可以實現,但是繁瑣且性能差,優雅更無從談起。

不妨換個角度思考,有沒有辦法讓文字不轉成圖片就可以用作 background-image 屬性的值呢?這樣就可以利用 background-repeat 實現平鋪效果了。

這時候可以考慮使用 SVG,因為 SVG 具有文本和圖像的雙重特性。看上去是文本,然而在很多場景可以當做圖片使用。

我們可以通過 SVG 的相關屬性精準控制字體位置、大小、顏色、透明度和旋轉角度等參數。如:

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <text x="50%" y="50%" font-size="30" fill="#a2a9b6" fill-opacity="0.3" font-family="system-ui, sans-serif" text-anchor="middle" dominant-baseline="middle" transform='rotate(-45, 100 100)'>水印文字</text>
</svg>

考慮到瀏覽器相容性,用作背景圖片時,建議將 SVG 編碼為 Base64(或轉義特定字元):

 

background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGV4dCB4PSI1MCUiIHk9IjUwJSIgZm9udC1zaXplPSIzMCIgZmlsbD0iI2EyYTliNiIgZmlsbC1vcGFjaXR5PSIwLjMiIGZvbnQtZmFtaWx5PSJzeXN0ZW0tdWksIHNhbnMtc2VyaWYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGRvbWluYW50LWJhc2VsaW5lPSJtaWRkbGUiIHRyYW5zZm9ybT0ncm90YXRlKC00NSwgMTAwIDEwMCknPuawtOWNsOaWh+WtlzwvdGV4dD48L3N2Zz4=");

 

 

水印安全

水印是用來保護信息安全的。信息要安全,首先要確保水印自身的安全,提高水印的防攻擊(篡改、刪除等)能力。

可見水印大都是基於 DOM 的,找到這個 DOM 節點,通過瀏覽器插件、抓包工具等在頁面上註入一段 JavaScript 或者 CSS 代碼對其進行篡改或刪除並不困難。

防止外部代碼篡改,一種思路是把水印元素封裝起來,與外部環境進行隔離。

Shadow DOM

在 Chrome 逐步統治瀏覽器江湖之後,谷歌正野心勃勃的推廣 Web Components 技術。該技術允許在 Web 中創建可重用的小部件或組件。組件化開發在前端業界已經流行相當長一段時間了,這主要得益於前端三大框架的推崇,但具體組件標準是由框架各自製定的,而 Web Components 可理解為 Web 標準化的組件。

Web Components 的一個重要特性就是“封裝”,即可以將標記結構、樣式和行為隱藏起來,並與頁面上的其他代碼相隔離。比如我們熟悉的 video 元素,它的進度條、按鈕等控制項都已被封裝。

 

 Shadow DOM 介面是“封裝”特性的關鍵所在,它可以將一個隱藏的、獨立的 DOM 附加到一個元素上。

 

 

為了提高 web 水印的隱蔽性,同時避免受外部代碼影響,從而在一定程度上防止篡改,可以考慮把水印元素放在 Shadow DOM 中。

來看下 Shadow DOM 的基本用法。使用 Element.attachShadow() 方法來將一個 shadow root 附加到任何一個元素上。它接受一個配置對象作為參數,該對象有一個 mode 屬性,值可以是 open 或者 closed 。open 表示可以通過頁面內的 JavaScript 方法來獲取 Shadow DOM。而 closed 則表示不可以從外部獲取 Shadow DOM 。

Element.attachShadow({mode: 'closed'});

 

 

樣式怎麼隔離呢?Shadow DOM 中的樣式本身就是隔離的,除非主動使用 CSS 變數、part 屬性等暴露,外部樣式是不會影響到組件內的。

Mutation Observer

Shadow DOM 提高了水印的隱蔽性,同時可以防止外部代碼修改。除此之外,還有一種常見的攻擊場景——人為修改,比如在瀏覽器控制台直接修改或刪除對應的 DOM 元素。

 

可以考慮“監聽”這種行為,一旦發生就馬上修複,比如重新插入一個。那怎麼實現這種“監聽”呢?現代瀏覽器中有多種觀察者(Observer),比如IntersectionObserverPerformanceObserverResizeObserverReportingObserverMutationObserver 等。其中,MutationObserver 就可以用來監聽 DOM 變動,DOM 的任何變動,比如節點的增減、屬性的變動、文本內容的變動,通過該 API 都可以得到通知。

所以可以使用 MutationObserver API 來監聽水印元素 DOM 變化,一旦監聽到 DOM 元素被修改或者刪除,就立即重新插入一個。

 

 

不可見水印(盲水印)

不可見水印也叫盲水印、隱水印,顧名思義是一種看不到的水印,看不到還要它做什麼呢?其實,不可見水印在一些對安全性要求較高的場景意義還是蠻大的。不可見水印通常具有比可見水印更好的隱蔽性和抗攻擊性。雖不可見,但通過一定的技術手段是可以將水印信息從其載體上提取出來的,這就使得其載體具備了溯源能力,在關鍵時刻往往能發揮大作用。

我總結不可見水印相對可見水印至少有以下三個明顯的優勢:

  • 更好的觀感。可見水印總給人一種“膏藥感”,甚至會引起部分人的不適,而不可見水印則不會有這個問題。
  • 更佳的隱蔽性。用戶基本感知不到水印的存在。
  • 更強的抗攻擊性。可見水印更容易受到攻擊,而不可見水印除了隱蔽性比較強之外,其自身往往還具備比較強的抗攻擊能力。

不可見水印(盲水印)屬於信息隱匿技術(也叫隱寫術),歷史悠久,手段繁多。在現代,隨著電腦網路技術的發展,數字產品的信息安全和版權保護也已成為信息隱匿技術的一個重要課題。隱寫術在數字音頻、數字視頻和數字圖像領域有著非常廣泛的應用。

Web 上基於 DOM 的盲水印大都不靠譜,而另一方面數字圖像是信息隱藏和數字水印領域研究最多和最早的一種載體,相較於 Web,數字圖像領域有著更為成熟的數字水印演算法。我們不妨先來看下數字圖像領域的常見盲水印技術。

在說數字水印之前,這裡介紹一些數字圖像的基礎知識。

數字圖像(點陣圖)是由像素(pixel)組成。

  • 非黑即白的二值圖像,1 個 bit 即可表示 1 個像素(黑白兩種狀態)。所以 1 個位元組(byte)可以表示 8 個像素。
  • 灰度圖,1 個像素有 256 種狀態(2 的 8 次方),需要 8 個 bit,即 1 個位元組。
  • 彩色的 RGB 圖,有 R / G / B 三個通道,每個通道 256 種狀態,使用 1 個位元組表示,共需 3 個位元組表示 1 個像素。
  • RGBA 圖,在 R / G / B 三個通道基礎上增加了一個透明度通道,256 種狀態,額外需要 1 個位元組,共需要 4 個位元組表示一個像素。

通常,考慮到計算速度和性能,圖像處理和圖像識別大都會將圖像轉成灰度圖或者選擇其中一個通道進行。

LSB 水印

如上文所述,灰度圖像的一個像素有 256 種狀態,通常用灰度值( 0-255 )表示,0 表示黑色,255 表示白色,灰度值越大表示亮度越高。

灰度可用一個位元組,即 8 比特二進位數表示,其中最高位對圖像的貢獻最大,最低位對圖像的貢獻最小,稱為最低比特位(Least Significant BitLSB)。

如果將一個圖像所有像素的比特位抽出來,就構成了 8 個不同的位平面,從 LSB(最低有效位 0)到 MSB(最高有效位 7)。位平面從低位到高位,圖像的特征逐漸變得複雜,細節不斷增加,相鄰比特的相關性也越強。而比特位越低包含的圖像信息就越少,最低位平面類似於隨機雜訊。因此,改變低位對圖像的成像質量影響不大。

LSB 水印就是利用了這一點,用水印信息替換載體圖像的最低比特位,這樣原圖像的 7 個高位平面就與表示水印信息的最低位平面組成了新的圖像。

 

 

 

LSB 水印魯棒性(防攻擊性)較差,水印信息容易被抹去。

頻域水印

將數字圖像用一個矩陣來表示,是圖像的空間域表示方法,LSB 就是在圖像的空間域隱藏信息,魯棒性較差。而在圖像信號的頻域(變換域)中隱藏信息要比在空間域中隱藏信息具有更好的魯棒性。那麼如何把圖像信號從空間域轉換到頻域呢?這裡就需要用到大名鼎鼎的 傅里葉變換 了。

法國數學家傅里葉大家一定不陌生,高數里就有傅里葉級數。

 

 傅里葉提出的傅里葉變換(Fourier transform)理論,表示能將滿足一定條件的某個函數表示成三角函數(正弦和/或餘弦函數)或者它們的積分的線性組合,可用於把信號從時間域(或空間域)變換到頻率域。

在此之前人們對信號的分析主要集中在空間域,傅里葉變換的提出為頻域分析奠定了基礎,有助於解決許多圖像的問題。

 

 

傅里葉變換在數字圖像處理領域有著極為重要的應用,圖像領域變換的實質是把圖像函數展開成具有不同空間頻率的正、餘弦信號的疊加,也就是說任何圖像都可以分解為若幹個頻率不同的亮度呈正弦變化的圖像之和。把圖像從空間域變換到頻率域後,就能夠實現對圖像數據進行不同頻率成分的提取。對於圖像信號來說,可以把灰度(亮度)看做頻率,傅里葉變換可作為圖像灰度值形成的空間域與其頻率域的橋梁。

在頻域中隱藏信息就是傅里葉變換在數字圖像處理領域的一個典型應用場景。通常多選擇在圖像頻域的中頻部分嵌入信息,因為高頻部分易於被各種信號處理方法破壞,而人的視覺又對低頻部分比較敏感,容易察覺低頻部分的變化。

在圖像頻域嵌入水印信息的大致流程為:把原始圖像通過離散傅里葉變換轉換到頻域(變換域),把水印文字信息混入,再經過離散傅里葉變換的逆變換,便得到了載有水印信息的圖像。水印信息隱匿性較好。

 

 

光說不練假把式,操練起來。

下圖是我隨手拍的鵝廠北京總部大樓一角。

 

 對上圖的一個通道進行離散傅里葉變換,在其變換域(頻域)加入水印文字(fransli)後,再進行離散傅里葉變換的逆變換,便得到了下圖。怎麼樣,看不到水印信息吧?

對上圖進行離散傅里葉變換,將圖片轉換到頻域(變換域),我們可以清楚的看到嵌入的水印文字(下圖)。

  

頻域盲水印具有比較好的防攻擊性,我們來測試一下。

我們截取圖像中的一部分並重新採樣,然後嘗試提取水印信息。

可以看到還是有很大概率可以提取到有效水印信息的。

 

 

 

Web 中的數字水印應用

上面介紹了幾種常見的不可見水印(盲水印)實現方式,其中魯棒性比較好的是基於頻域的數字圖像盲水印,但這種水印主要是針對數字圖像,而 Web 上的內容載體並不一定都是圖片,常見的需要加水印的載體除了圖片還有文本、表格等,這些場景該如何應用頻域盲水印呢?

或許,Canvas 就是答案。

Reference

 

作者:fransli

本文來自博客園,作者:古道輕風,轉載請註明原文鏈接:https://www.cnblogs.com/88223100/p/Exploring-Web-Watermarking-Technology.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 柯煜昌 青雲科技研發顧問級工程師 目前從事 RadonDB 容器化研發,華中科技大學研究生畢業,有多年的資料庫內核開發經驗。 文章字數 3800+,閱讀時間 15 分鐘 背景 MySQL 5.7 的字典信息保存在非事務表中,並且存放在不同的文件中(.FRM,.PAR,.OPT,.TRN,.TRG 等 ...
  • MySQL InnoDB引擎在Repeatable Read(可重覆讀)隔離級別下,到底有沒有解決幻讀的問題? 網上眾說紛紜,有的說解決了,有的說沒解決,甚至有些大v的意見都無法達成統一。 今天就深入剖析一下,徹底解決這個幻讀的問題。 解決幻讀問題之前,先普及幾個知識點。 ...
  • GreatSQL社區原創內容未經授權不得隨意使用,轉載請聯繫小編並註明來源。 GreatSQL是MySQL的國產分支版本,使用上與MySQL一致。 前言 實驗 總結 前言 資料庫的優化器相當於人類的大腦,大部分時候都能做出正確的決策,制定正確的執行計劃,走出一條高效的路,但是它畢竟是基於某些固定的規 ...
  • Oracle實現金額小寫轉大寫函數 今天工作的時候遇到了,然後上網百度了一下,發現了有個大佬寫了一個很牛的函數,在此記錄下來。 原文:http://www.itpub.net/thread-240281-1-1.html 函數: create or replace function F_upper_ ...
  • 開心一刻 晚上,女兒眼噙淚水躺在床上 女兒:你口口聲聲說愛我,說陪我,卻天天想著騙我零花錢,你是我親爹嗎? 我:你想知道真相 女兒:想! 我:那你先給爸爸兩百塊錢! 環境準備 MySQL 不同版本 利用 docker 搭建了 7 個不同版本的 MySQL 5.5.62 5.6.51 5.7.36 8 ...
  • 問題解決秘籍 遇到問題,第一個請登錄蘋果開發者官網 檢查一遍賬號是否有許可權,是否被停用,是否過期,是否有協議需要同意,並且在右上角切換賬號後檢查所有關聯的賬號是否工作正常,apple賬號的郵箱也是個重要的地方,當有ipa上傳,賬號有發生變化,被停用,apple經常發送一些郵件,去檢查郵件通知,根據郵 ...
  • 在項目中出現多重嵌套情況時,會出現無法滑動的場景,比如經常碰到的場景 ViewPager -> Fragment -> RecyclerView -> RecyclerView | ViewPager 最外層是一個可滑動的 tabLayout+ViewPager,ViewPager 中是多個 Fra ...
  • AR作為一項增強現實技術,帶來了虛擬數字世界與現實世界的深度融合,這種虛實融合,不僅能應用於虛擬汽車展示、虛擬室內設計等視覺交互場景,更可通過動作交互控制虛擬世界場景,實現無邊界的人機互動。 比如人們在拍攝短視頻時,可以不接觸屏幕,僅通過做出特定手勢來控制特效切換;也可以在拍照時通過手勢識別控制快門 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...