我們來做一個不可破解的驗證碼

如果你因爲網站數據一直被爬,如果你因爲活動一直被刷,如果你的短信通道被當成人肉炸彈,如果你的論壇被機器人野蠻刷帖,如果你的賬戶系統一直被暴力破解,如果你用了各種驗證碼包括極驗也根本沒用,你可以來這裏瞭解一下 https://yuan.shuidi.cn

我們先來分析一下市面上的驗證碼

1、明顯漏洞驗證碼

 

有明顯漏洞的驗證碼 一般是根本就不明白驗證碼是用來幹什麼的程序員設計出來,可能是產品設計上有個驗證碼,好,那我實現一個,或者是外包公司實現功能即可,根本不管客戶死活

下面是一個案例

給用戶一個數學運算,然後求結果, 結果這個數學運算,用字符的形式輸出到頁面上,而不是保存成一張圖片,這種驗證碼,形同虛設

 

2、數字,字母,中文驗證碼

 

這種驗證碼從互聯網出現就存在了,數字,字母,中文,干擾線,噪點,旋轉,扭曲,重疊,各種手段,但是還是無法去除特徵太明顯,組合結果太少的情況,用深度學習等ai手段很容易識別,市面上的一些orc的接口也能簡單識別

所以這種驗證碼 在2019年的今天已經很無力了,如果你做過投票活動,你就會知道,刷票公司破解你的驗證碼是有多容易

 

 

3、極驗驗證碼

極驗驗證碼,號稱行爲識別,其實沒那麼高端,如果拋開復雜的js混淆邏輯,其實很簡單,寫個算法破解圖片上的滑塊缺口位置很容易(一個二值化就ok),複雜的只是極驗的js混淆加密流程,但是客戶端代碼就是客戶端代碼,它是百分百可以破解的,只要你有足夠的耐心,慢慢調試,總能找到最後的邏輯,所以極驗的驗證碼並不是那麼牢靠,市面上第三方破解極驗的服務一大堆也很便宜,後續我會寫一篇破解極驗的文章

 

 

我們如何來設計一個幾乎無法破解的驗證碼呢?

它只要滿足一個要求,驗證碼的結果,用機器很難,或者要花費很長時間,花費很多代價纔可以識別出結果

那些複雜的js混淆,各種花裏胡哨的寫法根本就沒有任何作用

 

下面我們來介紹我們將要設計驗證碼的核心思路

 

將一張圖旋轉到一個隨機的角度,然後讓用戶去識別圖片的正確方向

 

 

人類通過自己的經驗用不到1s的時間就可以識別出這張圖的方向

 

但是利用目前的機器學習模型,如果要做到圖片方向的識別還非常困難

當然有的同學說了,這個圖就360張可能,我人工把這張圖擺正,然後再生成360張旋轉圖,一張一張對比即可,把圖片md5存到數據庫,再加個索引,不要太簡單

你說的很對,如果就這麼一張圖,你確實可以這麼做,

解決這個難題很簡單

生成的圖片我們給一個10*10的隨機偏移量,這樣,一張圖片,我們可以生成 10*10*360張圖,然後我們在圖片裏隨機的加空白點,這樣,就無法md5做成索引查找了,比對只能遍歷

然後我們再通過網絡爬蟲爬取那些沒有版權的圖片,讓圖片有上萬張,你還可以一張一張的用人工擺正來識別碼?

10000 * 10 * 10 *360

有的同學說可以,我有的時間

好,假設我我有一萬張圖,我一個小時放10張圖出來,每個小時的圖都不一樣,你可以和我耗40多天嗎?

我有10萬張圖呢?

 

是不是很刺激,想想那些spider們,刷票公司看着我們的驗證碼,望洋興嘆是不是很刺激 ,哈哈哈哈哈

那就趕緊行動起來吧

 

放一下生成旋轉圖的 php 代碼,你可以將隨機出來的角度 存到session裏,或者memcache裏,就ok啦,記得每次校驗完,要把值清空噢,不管正確與否,

 

        $origin_width = 200;
        $origin_height = 200;

        //取一張圖 $img_path 是一張210*210的jpg圖片
        $origin_img = imagecreatefromjpeg($img_path);


        //重新畫
        $src_img = imagecreatetruecolor($origin_width,$origin_height);
        $alpha = imagecolorallocatealpha($src_img, 0, 0, 0, 127);
        imagefill($src_img, 0, 0, $alpha);
        $src_x = rand(0,9);
        $src_y = rand(0,9);
        imagecopyresampled($src_img,$origin_img,0,0,$src_x,$src_y,$origin_width,$origin_width,$origin_width,$origin_width);

        $angle = rand(30,330);

        $src_img = imagerotate($src_img,-1*$angle,0);
        $w = imagesx($src_img);
        $h = imagesy($src_img);

        $r = $origin_width/2-4;//防止邊緣問題,稍微取小一點
        $real_r = $w/2;

        //生成一張圖
        $img = imagecreatetruecolor($origin_width-8, $origin_height-8);//防止邊緣問題,稍微畫小一點
        imagesavealpha($img, true);
        $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
        imagefill($img, 0, 0, $bg);

        for ($x = 0; $x < $w; $x++) {
            for ($y = 0; $y < $h; $y++) {
                $rgbColor = imagecolorat($src_img, $x, $y);
                if (((($x - $real_r) * ($x - $real_r) + ($y - $real_r) * ($y - $real_r)) < ($r * $r))) {
                    imagesetpixel($img, $x-($real_r-$r), $y-($real_r-$r), $rgbColor);
                }
            }
        }
        imagepng($img);
        //銷燬圖片
        imagedestroy($img);

放一個我們已經上線的案例

 

 

雲版本已上線,目前免費使用  https://yuan.shuidi.cn

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章