奇思妙想之用JS給圖片加口令
本文展示一種用JS給圖片加口令的方法,可以將任意圖片轉(zhuǎn)化為html,輸入正確的口令才能打開查看圖片。
效果如下:
效果說明
- 它最終只有一個(gè)文件。并非一張圖片和一個(gè)html,不是在html中引用圖片,而是將圖片放入了html。
- 打開時(shí),必須輸入的正確口令,口令錯(cuò)誤則不能打開。
- 口令不能被獲取!查看html源碼無法找到口令,雖然口令確實(shí)是存放在文件中。
直入主題,下面介紹此效果的技術(shù)原理和實(shí)現(xiàn)方法:
技術(shù)原理
- 將圖片轉(zhuǎn)化為base64字符串,這樣可以直接將字符串寫入html,而無需引用外部的圖片。
- 打開時(shí)要求輸入口令、口令校驗(yàn)都由JS實(shí)現(xiàn)。
- 口令隱藏,不能通過查看網(wǎng)頁源碼獲取。
實(shí)現(xiàn)方法
1. 將圖片放入網(wǎng)頁的方法非常簡單,只要將圖片轉(zhuǎn)為base64編碼字符即可,轉(zhuǎn)換使用canvas進(jìn)行,代碼如下:
- function getImageBase64(img, ext) {
- //創(chuàng)建canvas DOM元素,并設(shè)置其寬高和圖片一樣
- var canvas = document.createElement("canvas");
- canvas.width = img.width;
- canvas.height = img.height;
- var ctx = canvas.getContext("2d");
- //使用畫布畫圖
- ctx.drawImage(img, 0, 0, img.width, img.height);
- var dataURL = canvas.toDataURL("image/" + ext);
- //返回的是一串Base64編碼
- canvas = null;
- return dataURL;
- }
- var img_path ="yxdj250x250.jpg";
- //網(wǎng)頁中需提前設(shè)定一個(gè)id為icon的img元素
- var user_icon = document.getElementById('icon');
- fileExt="";
- //獲取base64編碼
- user_icon.src = img_path;
- user_icon.onload = function () {
- //base64編碼
- base64 = getImageBase64(user_icon, fileExt);
- console.log(base64);
- }
操作方法:準(zhǔn)備一張圖片,上面的代碼中使用的是:yxdj250x250.jpg,實(shí)際操作時(shí)換為自己要轉(zhuǎn)化的圖片。
將以上js代碼放入html中,打開運(yùn)行,然后從瀏覽器的調(diào)試工具中可以看到輸出了圖片對應(yīng)的base64編碼,效果如下:
這時(shí),如果要在網(wǎng)頁中顯示圖片,只要使用img src=”"方法,將上面輸出的編碼填入src即可。
2. 接下來實(shí)現(xiàn)口令功能,代碼如下:
- var pass = prompt('請輸入口令','');
- if (pass != "123"){
- history.go(-1);
- alert("口令錯(cuò)誤。");
- }
- else{
- show_pic();
- }
從以上的功能邏輯可以看出,如果輸入口令:123,則顯示圖片,反之不能打開。
3. 口令能被直接查看到,顯然是不行的。那樣隨便誰懂點(diǎn)電腦知識(shí)都可以獲取口令,就失去了口令保護(hù)的效果。
或許有人會(huì)說:不要使用名文比較,使用變量比較、把口令字符隱藏起來。但也不是個(gè)有效的辦法。懂點(diǎn)技術(shù)的都知道瀏覽器可以斷點(diǎn)調(diào)試的,只要來到斷點(diǎn)處,就可以直接查看密碼:
真正有效的辦法是什么呢?JS代碼混淆加密!口令也是存儲(chǔ)在JS代碼中的,只要將代碼混淆加密,口令也會(huì)一起被加密,就沒辦法找到密碼了,而且還可以防斷點(diǎn)調(diào)試。
下面是混淆加密后的代碼效果:
JS代碼混淆,國際上有JScrambler,國內(nèi)有JShaman,混淆效果差不多,JShaman的使用起來更方便一些,中文界面、操作也更符合國人習(xí)慣。
在進(jìn)行代碼混淆時(shí),一定要使用“字符串加密”功能,因?yàn)檫@是我們進(jìn)行混淆的關(guān)鍵需求,只要選了這一項(xiàng),密碼才會(huì)隱藏起來。
有的技術(shù)同學(xué)很可能有反對意見,認(rèn)為JS混淆加密后是可以還原的。
關(guān)于這個(gè)想法,要分情況。
如果是用unescape、escape、eval進(jìn)行的初級加密,那是可以逆的,可以解密的。
而如果是真正的高強(qiáng)度混淆加密,是不可解的。
這個(gè)需要從理原上深度的解釋,比如JShaman這種混淆加密,使用的并非是簡單的可逆加密。
而是先對JS源代碼進(jìn)行詞法分析、語法分析,分離出變量、常量、函數(shù)、關(guān)鍵字等,生成語法樹;然后進(jìn)行變量變形、常量陣列化、加密,插入僵尸代碼、加入反調(diào)試、再平展控制流等等,***再重新生成代碼。
是對代碼進(jìn)行了重建的,不可逆的。
還是不太相信嗎?
好的,我們來實(shí)際檢測一下,逆一次。
先進(jìn)行代碼混淆:
再對對結(jié)果代碼進(jìn)行反混淆。常用的是esprima、escodegen。
這里在nodejs的環(huán)境下使用:
首先安裝這兩個(gè)組件:
- npm install esprima
- npm install escodegen
然后準(zhǔn)備以下代碼:
然后執(zhí)行,這時(shí)會(huì)輸出反混淆結(jié)果:
可見,反混淆后得到的代碼,跟原始代碼差別非常大,多了很多很多復(fù)雜的邏輯關(guān)系,字符也是混亂不堪,代碼幾乎是無法閱讀,更別說理解出原本代碼含義了。
從這解密后的代碼中,當(dāng)然也沒辦法找到原來的密碼“123”。
混淆與反混淆的問題暫告一段落,如果有人還反駁:一點(diǎn)點(diǎn)的讀,只要肯花時(shí)間,三天、一個(gè)月,總能慢慢讀懂。那就屬于鉆牛角了。
我們回到正文。因?yàn)閳D片的base64編碼字符串比較長、內(nèi)容量大,混淆加密時(shí),建議只對關(guān)鍵代碼進(jìn)行混淆,否則生成的代碼可能會(huì)太過龐大。
經(jīng)過這一系列操作后,一張被口令保護(hù)的圖片就生成了。
掌握了一個(gè)很絢酷的技能吧!
同時(shí),這個(gè)技能在很多場合,是有實(shí)際用途的,相信你會(huì)遇的到。