關於EasyPass

簡介

很久以前有一個想法,只用一個密碼,通過hash的方式生成所有網站的密碼。具體是通過一個原密碼+一些任意字符串,生成不同的字符串結果。
於是就寫了這個EasyPass,Demo在http://pw.nya.pm/
下面記錄下自己實現的過程

生成密碼表

    function getEArray($hasNumber, $hasPunctuation){
        // Array initialize
        $eArray = [];
        // Set the Punctuation's ASCII
        $punc = [33, 35, 36, 37, 38, 43, 45, 46, 63, 64, 95, 126];
        // Traversal all ASCII(10)
        for($i=0; $i<=127; $i++){
            // If hasNumber, push number to the array
            if($hasNumber == "true"){
                if($i>=48 and $i <= 57)
                    array_push($eArray, chr($i));
            }

            // If hasPunctuation, push punctuation to the array
            if($hasPunctuation == "true"){
                if(in_array($i, $punc)){
                    array_push($eArray, chr($i));
                    array_push($eArray, chr($i));
                }
            }
            
            // Push letters to the array
            if($i>=65 and $i <= 90)
                array_push($eArray, chr($i));
            if($i>=97 and $i <= 122)
                array_push($eArray, chr($i));
        }
        // Get the password for encrypting
        $encryptPass = __PASS__;
        $encryptPassN = hash('sha512', base64_encode($encryptPass));

        $i = 0;
        $j = 0;
        $arrayLength = sizeof($eArray);
        while( isset($eArray[$i]) ){
            $j = ($j+ord($encryptPassN[$i])) % $arrayLength;
            $temp = $eArray[$i];
            $eArray[$i] = $eArray[$j];
            $eArray[$j] = $temp;

            $i++;
        }

        return $eArray;
    }

這個函數帶兩個參數,分別決定是否含有數字和是否含有標點符號。函數先通過ASCII生成一張順序的密碼表,然後通過PASS這個常量(在Config.php中,可自定義)的base64編碼的SHA512值進行亂序。
考慮到標點符號比較少,push兩次到array裏面。

取密碼

    function genPasswd($eArray, $newPass, $length){
        // init output data
        $result = "";
        // Get the array's length
        $arrayLength = sizeof($eArray);
        // Set a pointer
        $pointer = 0;
        // Generate password words by words
        for($i=0; $i<$length; $i++){
            // Set random offsets
            $t = $this->findWhere($newPass[$i]);
            $pointer += $t;
            // Get chars
            $char = $eArray[$pointer % $arrayLength];
            // Combine them
            $result .= $char;
        }
        return $result;
    }

    function findWhere($char){
        $t = ord($char);
        if ($t >= 48 and $t <= 57){
            return $t-47;
        }
        elseif ($t >= 97 and $t <= 122){
            return $t-86;
        }
        else{
            return $t%32;
        }
    }

之後便是取密碼,包括了密碼表,原密碼,長度三個參數。通過一個pointer抓密碼表裏面的值,pointer遞增的值通過逐位取newPass的字符計算得出。最後增加至result內。

标签: php, EasyPass