PHP/JAVA 加密網站地址——從根本解決盜連

來源:互聯網
上載者:User

 網站防止圖片等內容盜鏈的方法多種多樣,其中最常用的方法就是通過HTTP訪問頭資訊,判斷訪問來源。理解TCP/IP通訊員裡的讀者都知道,由於HTTP頭資訊處理是在OSI模型的應用程式層,所以,編造一些假的HTTP頭資訊發送給伺服器,並不需要什麼特殊的技術或者工具。
下面的示範中,是利用wget命令類比Firefox2瀏覽器進行HTTP基本認證的例子。依照它的訪問,HTTP伺服器根本就分辨不出來是Firefox瀏覽器還是wget發送的HTTP請求,而且,訪問來源也被欺騙了。

wget --http-user=登陸ID --http-password=登陸密碼 --no-cache --referer=訪問來源 /n<br /> --user-agent="User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14"
            
通過HTTP頭資訊防止盜鏈,是一種典型的防君子不防小人的做法。

面向網路的WEB內容,都是公開的,大多數情況是不需要考慮盜鏈問題的。如果要限制某些內容,僅針對於某個特定群體使用者的瀏覽,可以通過CGI進行使用者認證。例如SNS、論壇以及WEB郵箱等等都具有這種功能。而訪問來源只是作為訪問日誌的一部分,用來搜集使用者活動資訊,並不是系統運行所必需的內容。

綜上所述,由於HTTP通訊協定自身的原因,防止盜鏈的方法中,判斷頭資訊是無法做到真正防盜鏈的。想要真正做到防止盜鏈只能通過以下兩個途徑:
1.通過CGI進行使用者認證,防止無關人員對目標內容的訪問:
  雖然,此方法無法防止擁有存取權限會員“盜鏈”,但是,對於防止不相干人員的盜鏈還是非常有效。
2.動態變換訪問路徑:
  此種防止盜鏈的方法很直接,就是讓盜鏈者得到的地址是無效的。而這個地址,只有在最先訪問的使用者手裡才有效。以下,本文將就如何對原始連結地址加密,進行討論。

本文所介紹的加密連結地址的方法,是一種利用XOR演算法的簡單的共有鑰加密。
電腦技術中經常使用的加密方法有兩種,一種是公開鑰加密(如SSL),一種是公有鑰加密(也叫秘祕密金鑰加密,如AES、BrowFish等)技術。公有鑰加密就是加密方和解密方擁有共同的鑰匙進行加密、解密。缺點是一旦鑰匙丟失,那麼,所有的加密處理都將報廢,被加密內容可以被任何擁有鑰匙的人得到。公開鑰加密方法可以解決這一難題,但是,本文中所介紹的連結地址加密處理,全部在伺服器內部進行,不涉及到泄漏加密鑰匙的問題,而且,加密鑰匙隨著訪問不同而不規則改變,也不存在泄漏解碼鑰匙的問題,所以將採用更簡單的共有鑰加密的方法。
連結地址加密原理如下:
1.當新的session被建立時,在session內亂數產生一個共有加密鑰匙。
2.圖片顯示串連時,伺服器端CGI自動對諸如內容地址、資料庫中的內容ID等進行加密,產生加密後的連結地址。
3.訪問加密後連結地址,伺服器提取session中的加密鑰匙,解密加密內容,返回請求內容。

為什麼使用XOR演算法:
比如一些圖片網站,如果對URL進行加密,若採用複雜的密碼編譯演算法,勢必會增加伺服器的負擔。
考慮到效能方面,筆者使用了XOR演算法。雖然此演算法容易被破解,但是,加密鑰匙的存留時間短暫,仍舊可以保持較高的安全性。
以下分別是使用了Java語言和PHP語言的加密代碼,謹供參考。

 

Java代碼:

import java.io.UnsupportedEncodingException;<br />import java.net.URLDecoder;<br />import java.net.URLEncoder;<br />public class XorTest {</p><p> public static void main(String[] args) throws UnsupportedEncodingException {<br /> //String value = "肉、蔬菜和水果";<br /> //String key = "蔬菜和水果";<br /> String value = "http://blog.csdn.net/froole/archive/2009/05/13/4176111.aspx";<br /> String key = "key";</p><p> // 加密前輸出<br /> print("加密前", value);<br /> // 加密處理<br /> byte[] byteEncodeArray = encode(value.getBytes(), key);<br /> value = new String(byteEncodeArray);</p><p> // 加密後輸出<br /> print("加密後", value);</p><p> // URL轉換處理<br /> String encode = URLEncoder.encode(value, "UTF-8");<br /> print("轉換URL", encode);<br /> String dencode = URLDecoder.decode(encode, "UTF-8");<br /> print("從URL回複", dencode);<br /> value = dencode;</p><p> // 解密<br /> byte[] byteDecodeArray = decode(value.getBytes(), key);<br /> value = new String(byteDecodeArray);</p><p> // 解密後輸出<br /> print("解密", value);<br /> }</p><p> /**<br /> * 加密處理<br /> * @param src<br /> * @param key<br /> * @return<br /> */<br /> private static byte[] encode(byte[] src, String key) {<br /> byte[] byteKeyArray = new byte[0];<br /> byte[] byteEncArray = new byte[src.length];</p><p> // 轉換加密鑰匙的迴圈處理<br /> while(byteKeyArray.length < src.length) {<br /> byteKeyArray = (new String(byteKeyArray) + key).getBytes();<br /> }</p><p> // 轉換<br /> for (int i = 0; i < src.length; i++) {<br /> byteEncArray[i] = (byte)(src[i]^byteKeyArray[i]);<br /> }<br /> return byteEncArray;<br /> }</p><p> /**<br /> * 解密<br /> * @param src<br /> * @param key<br /> * @return<br /> */<br /> private static byte[] decode(byte[] src, String key) {<br /> return encode(src, key);<br /> }</p><p> /**<br /> * 轉換成16進位文字<br /> * @param value<br /> * @return<br /> */<br /> private static String getDump16(byte[] value) {</p><p> StringBuffer buf = new StringBuffer();</p><p> for (int i = 0; i < value.length; i++) {<br /> String hex = Integer.toHexString((int)value[i] & 255);</p><p> // 添補前4位<br /> hex = "0000" + hex;<br /> hex = hex.substring(hex.length() - 4, hex.length());</p><p> // 添加空白並且每10位變行(空白區切り、10桁ずつ改行)<br /> buf.append(hex + (i % 10 == 9?System.getProperty("line.separator"):" "));<br /> }<br /> return buf.toString().trim();<br /> }</p><p> private static void print(String title, String value) {<br /> System.out.println("【 " + title + " 】");<br /> System.out.println("-----------------------------");<br /> System.out.println(value);<br /> System.out.println(getDump16(value.getBytes()));<br /> System.out.println();<br /> System.out.println();<br /> }<br />}

 

PHP代碼:

// XOR encrypt/descript<br />function xor_encrypt($plain,$key) {<br /> $seed=str_repeat($key,strlen($plain));<br /> return bin2hex($plain^$seed);<br />}<br />function xor_decrypt($enc,$key) {<br /> $seed=str_repeat($key,strlen($enc));<br /> return pack("H*",$enc)^$seed;<br />}<br />// 測試代碼<br />$key='v';<br />$enc=xor_encrypt("http://blog.csdn.net/froole/archive/2009/05/13/4176111.aspx",$key);<br />echo "enc:[".$enc."]/n";<br />echo "Org:[".xor_decrypt($enc,$key)."]/n";

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.