2012年2月22日水曜日

ブラウザに表示されている画像をとにかく保存しにくくする方法

知名度の向上を目指して秘蔵の画像をWebで公開したいが,コンテンツの保護の観点から無闇にコピーされたくないってのは割と考えられ得るケースなんだけれど,そもそもインターネットがデータのコピーを授受することで成り立っている以上,このような要件を完全に満たすことは出来ない.つまりブラウザ単体では,どんなに頑張ってもせいぜいローカルコンピュータに保存するのを妨害するくらいが関の山である.

じゃあどれくらい妨害できるのかってことを考えてみた.ブラウザの環境としてはcss3,HTML5,javascriptを想定する.なお,ユーザビリティーなんてものは一切考慮しない.そもそもユーザーの権利を妨害している時点で使い勝手は最悪なはず.


すると大体こんなところに落ち着こうか.
  • 表示させたい画像はサーバー側で暗号化しておき,canvasを用いたクライアントスクリプトによってブラウザ内部で復号化するようにする.
    • 画像ファイルのURIを直接指定しても意味のある画像に見えない.
    • ブラウザキャッシュからの画像の抽出を防ぐ.
  • 画像の復号化ロジックが記述されているjavascriptは難読化しておく.場合によっては復号化キーの取得を行うことでスクリプト単体では動作しないようにしてしまう.
  • 復号化した画像はimg要素やbackground-imageスタイルとして表示するのではなく,:before擬似要素のcontentとして表示する.contentに指定するurlとしてcanvasのgetDataURLメソッドから得られた文字列を指定する.
    • こうすると画像を右クリックした際の保存メニューや背景の保存メニューを出さずに済む.よって画像のカジュアルコピーを防ぐことが出来る.
  •  画像を表示したい部分にtabindexを指定し,フォーカスの移動を有効化しておく.onfocus,onblurイベントに上記のスタイルを記述したstyle要素を追加・削除するスクリプトを登録する.画像エレメントにフォーカスがある時だけ画像が表示されるようにする.
    • 印刷・ページの保存等のブラウザの他の機能を呼び出すと画像からフォーカスが移るので,画像が非表示となる.
    • 外部ツールを呼び出した際に画像がキャプチャされてしまう可能性を少なくする. 
大体こんな感じ.canvas+:before+:focusが連携して画像を表示する.とっても意地悪.

内部で画像を加工する都合上,ソースとなる画像のフォーマットは劣化のないpng,gif画像が適当か.なおクロスドメインでの画像加工はcanvasの仕様上できないので注意.
もしくはcanvasの構造は大体byte配列と思って間違いないので,工夫の仕方によってはどのようなデータでも画像に復号化出来るはずだ.

ただこんなに頑張ってもプリントスクリーンは防ぐことはできない.一般にprint screenキーを受け付ける順番がOS→ブラウザの順だからだ.同様に動画キャプチャとか,画面をカメラで撮るなんてのも防げない.これらは全てブラウザの外の出来事であるから,これ以上の妨害は諦めるしかない.
またWeb開発用のツールを導入している環境では中で何をしているのか分かってしまうかもしれない.(でもそのようなツールを導入している時点で一般的でないはず)

ちなみに,プリントスクリーンすら許さないためにはどうすればいいかを考えるにあたり,ブラウン管の仕組みにも着目してみた.ブラウン管のようなインターレース表示では,人間の目で見た時のみ正しい像として認識できるので,この仕組みに倣い高速に画像を入れ替えて1フレームのみでは画像全体を表示させないようにする方法も考えてみた.
が,実際に試してみるとjavascriptの動作タイミングが不安定であったり,どうしても液晶の画面がちらついてしまったりと,全く実用に耐えるものではなかった.心理学的に気にならないような画像の分解・合成法があるのなら話は別なのだろうが,簡単に実現可能といったものではなかった.

どのみちユーザビリティーを著しく損なう可能性があるので,ご利用は計画的に.

0 件のコメント:

コメントを投稿