>

session_start() 에 전화하면  또는 session_regenerate_id() , PHP는 세션 ID에 임의의 문자열로 보이는 것을 생성합니다. 내가 알고 싶은 것은 임의의 문자 시퀀스입니까, 아니면 uniqid() 와 같습니다.  기능?

임의의 캐릭터 일 경우 이론적으로는 충돌을 일으킬 수 없습니까? 사용자 A가 로그인 한 다음 사용자 B가 로그인했지만, 가능성이 거의 없지만 사용자 B가 동일한 세션 ID를 생성 한 경우 사용자 B는 사용자 A의 계정에 액세스하게됩니다.

PHP가 동일한 ID를 가진 세션이 이미 존재하는지 확인하고, 그렇다면, 다시 ID를 재생성하더라도 ... 가비지 이후에도 동일한 ID를 두 번 생성하는 시스템은 필요하지 않습니다 수집-아마도 테이블을 저장하고 도용 가능성이나 그 밖의 것들을 확인하고 싶습니다.

독특하지 않다면 어떻게 독창성을 강화해야합니까? 오히려 내가 만드는 모든 스크립트보다 PHP 구성을 사용하여 구현하고 싶습니다. PHP 세션에 대한 좋은 점은 뒤에서 기술적 인 세부 사항에 대해 걱정하지 않습니다.


  • 답변 # 1

    PHP가 기본적으로 세션 ID를 생성하는 방법을 알고 싶다면 Github에서 소스 코드를 확인하십시오.확실히 무작위가 아니며이러한 구성 요소의 해시 (기본값 : md5)를 기반으로합니다 (코드 스 니펫의 310 행 참조).

    <올> 클라이언트의

    IP 주소

    현재 시간

    PHP 선형 합동 생성기-의사 난수 생성기 (PRNG)

    OS 별 임의 소스-OS에 임의 소스가있는 경우 (예 :/dev/urandom)

    OS에 사용 가능한 임의의 소스가있는 경우 세션 ID가되는 목적으로 생성 된 ID의 강도가 높습니다 (/dev/urandom이며 다른 OS 임의 소스는 (일반적으로) 암호화 적으로 안전한 PRNG입니다). 그러나 그렇지 않은 경우 만족합니다.

    세션 식별 생성의 목표는 다음과 같습니다.

    <올>

    동일한 값으로 두 개의 세션 ID를 생성 할 확률을 최소화

    임의의 키를 생성하고 사용중인 키를 누르는 것은 계산 상 매우 어려운 과제입니다.

    이것은 PHP의 세션 생성 접근 방식에 의해 달성됩니다.

    고유성을 절대 보장 할 수는 없지만확률은 동일한 해시를 두 번 두 드릴 정도로 낮으므로 일반적으로 걱정할 가치가 없습니다.

  • 답변 # 2

    여기 ID를 생성하는 코드 : Session.c

    특히 php_session_create_id  기능 :

    PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */
    {
        PHP_MD5_CTX md5_context;
        PHP_SHA1_CTX sha1_context;
    #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
        void *hash_context = NULL;
    #endif
        unsigned char *digest;
        int digest_len;
        int j;
        char *buf, *outid;
        struct timeval tv;
        zval **array;
        zval **token;
        char *remote_addr = NULL;
        gettimeofday(&tv, NULL);
        if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
            Z_TYPE_PP(array) == IS_ARRAY &&
            zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS
        ) {
            remote_addr = Z_STRVAL_PP(token);
        }
        /* maximum 15+19+19+10 bytes */
        spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);
        switch (PS(hash_func)) {
            case PS_HASH_FUNC_MD5:
                PHP_MD5Init(&md5_context);
                PHP_MD5Update(&md5_context, (unsigned char *) buf, strlen(buf));
                digest_len = 16;
                break;
            case PS_HASH_FUNC_SHA1:
                PHP_SHA1Init(&sha1_context);
                PHP_SHA1Update(&sha1_context, (unsigned char *) buf, strlen(buf));
                digest_len = 20;
                break;
    #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
            case PS_HASH_FUNC_OTHER:
                if (!PS(hash_ops)) {
                    php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");
                    efree(buf);
                    return NULL;
                }
                hash_context = emalloc(PS(hash_ops)->context_size);
                PS(hash_ops)->hash_init(hash_context);
                PS(hash_ops)->hash_update(hash_context, (unsigned char *) buf, strlen(buf));
                digest_len = PS(hash_ops)->digest_size;
                break;
    #endif /* HAVE_HASH_EXT */
            default:
                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");
                efree(buf);
                return NULL;
        }
        efree(buf);
        if (PS(entropy_length) > 0) {
    #ifdef PHP_WIN32
            unsigned char rbuf[2048];
            size_t toread = PS(entropy_length);
            if (php_win32_get_random_bytes(rbuf, MIN(toread, sizeof(rbuf))) == SUCCESS){
                switch (PS(hash_func)) {
                    case PS_HASH_FUNC_MD5:
                        PHP_MD5Update(&md5_context, rbuf, toread);
                        break;
                    case PS_HASH_FUNC_SHA1:
                        PHP_SHA1Update(&sha1_context, rbuf, toread);
                        break;
    # if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
                    case PS_HASH_FUNC_OTHER:
                        PS(hash_ops)->hash_update(hash_context, rbuf, toread);
                        break;
    # endif /* HAVE_HASH_EXT */
                }
            }
    #else
            int fd;
            fd = VCWD_OPEN(PS(entropy_file), O_RDONLY);
            if (fd >= 0) {
                unsigned char rbuf[2048];
                int n;
                int to_read = PS(entropy_length);
                while (to_read > 0) {
                    n = read(fd, rbuf, MIN(to_read, sizeof(rbuf)));
                    if (n <= 0) break;
                    switch (PS(hash_func)) {
                        case PS_HASH_FUNC_MD5:
                            PHP_MD5Update(&md5_context, rbuf, n);
                            break;
                        case PS_HASH_FUNC_SHA1:
                            PHP_SHA1Update(&sha1_context, rbuf, n);
                            break;
    #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
                        case PS_HASH_FUNC_OTHER:
                            PS(hash_ops)->hash_update(hash_context, rbuf, n);
                            break;
    #endif /* HAVE_HASH_EXT */
                    }
                    to_read -= n;
                }
                close(fd);
            }
    #endif
        }
        digest = emalloc(digest_len + 1);
        switch (PS(hash_func)) {
            case PS_HASH_FUNC_MD5:
                PHP_MD5Final(digest, &md5_context);
                break;
            case PS_HASH_FUNC_SHA1:
                PHP_SHA1Final(digest, &sha1_context);
                break;
    #if defined(HAVE_HASH_EXT) && !defined(COMPILE_DL_HASH)
            case PS_HASH_FUNC_OTHER:
                PS(hash_ops)->hash_final(digest, hash_context);
                efree(hash_context);
                break;
    #endif /* HAVE_HASH_EXT */
        }
        if (PS(hash_bits_per_character) < 4
                || PS(hash_bits_per_character) > 6) {
            PS(hash_bits_per_character) = 4;
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now");
        }
        outid = emalloc((size_t)((digest_len + 2) * ((8.0f / PS(hash_bits_per_character)) + 0.5)));
        j = (int) (bin_to_readable((char *)digest, digest_len, outid, (char)PS(hash_bits_per_character)) - outid);
        efree(digest);
        if (newlen) {
            *newlen = j;
        }
        return outid;
    }
    
    

    실제 ID는 시간과 같은 여러 가지 요소의 해시입니다. 따라서 충돌이 발생할 가능성이 있지만 가능성은 매우 낮습니다. 동시 사용자가 많지 않으면 걱정할 필요가 없습니다.

    그러나 정말로 걱정된다면 다른 해시 알고리즘 session.hash_function을 설정하여 엔트로피를 높일 수 있습니다

    활성 세션을 모니터링하는 한,이 질문은 잘 다룹니다. PHP를 사용하여 활성 세션을 볼 수 있습니까?

    단일 컴퓨터에서 단일 PHP 인스턴스를 사용하는 경우, 실제로 할당하기 전에 ID가 이미 존재하는지 확인하는 내장 세션 관리자가 있습니다. 그러나 여러 인스턴스 또는 여러 머신을 실행중인 경우 다른 머신이 할당 한 ID를 알 수 없습니다.

  • 이전 .net - iis6에서 파일 업로드 크기 제한 늘리기
  • 다음 Facebook API/PHP - 페이스 북 api/php - fb graph api를 통해 사용자의 프로필 이미지를 변경할 수 있습니까?