회원가입 같은 것을 할때 입력하는 암호가 보안에 안전한지 여부를 반환하는 함수를 만들었습니다.


<?php
/**
 * @brief 암호의 보안레벨을 반환한다.
 * @details 레벨은 0~3이며 숫자가 높을수록 보안이 뛰어남.\n
 * 보안레벨 0은 사용하지 않는 것이 좋다.
 * @param $password string 암호
 * @param $point_data array 계산된 점수 정보
 * @return int 보안레벨
 */
public static function password_level($password, &$point_data = null) {
    $point_data = array();
 
    ## 문자열 분석 및 점수계산 ##
    $char_point = 0; // 문자 점수
    $change_point = 0; // 변환 점수
 
    $unique_char = array(); // 고유문자
    $old_char = $password[0]; // 이전문자(시작은 첫문자와 똑같게)
    for ( $i = 0; $i < strlen($password); $i++ ) {
        $char = $password[$i];
 
        // 고유문자
        $unique_char[$char] = 0;
 
        // 문자 점수(6 ~ 16자 기준): 6 ~ 7.2
        if ( preg_match('/[0-9]/', $char) ) {
            $char_point += 1;
        } else if ( preg_match('/[a-zA-Z]/', $char) ) {
            $char_point += 1.1;
        } else if ( preg_match('/[\x21-\x2F\x3A-\x40\x5B-\x60\x7B-\x7E]/', $char) ) {
            $char_point += 1.2;
        } else {
            return 0;
        }
 
        // 변환 점수(6 ~ 16자 기준): 0.05 ~ 1.5
        $gap = ord($char) - ord($old_char);
        if ( abs($gap) > 1 ) { // 연속성 없이 변환
            $change_point += 0.1;
        } else if ( $gap < 0 ) { // 역순서로 변환
            $change_point += 0.05;
        }
        $old_char = $char;
    }
 
    // 문자길이 점수(6 ~ 16자 기준): 0 ~ 2
    $length_point = floor(strlen($password) / 6);
 
    // 고유문자 점수(16자 기준): 1 ~ 16
    $unique_point = count($unique_char);
 
    // 전체 점수(6 ~ 16자 기준): 0 or 0.3 ~ 345.6
    $total_point = $char_point * $change_point * $length_point * $unique_point;
 
    // 점수정보 참조 배열
    $point_data = array(
        'char' => $char_point,
        'change' => $change_point,
        'length' => $length_point,
        'unique' => $unique_point,
        'total' => $total_point,
    );
 
    ## 보안 레벨 반환 ##
    // 전체 점수를 위한 4종류 점수를 각각 '(최대값 - 최소값) / 레벨'의 값으로,
    // 4종류 점수를 각각 레벨별로 계산하여 레벨별 점수범위를 구했음
    if ( $total_point > 0 && $total_point <= 16.96 ) {
        return 1;
    } else if ( $total_point > 16.96 && $total_point <= 137.36 ) {
        return 2;
    } else if ( $total_point > 137.36 ) {
        return 3;
    } else {
        return 0;
    }
}
?>
Tagged with:  

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">