The SessionID generation principle of PHP

Source: Internet
Author: User
Tags sha1

as a Web program ape, we are certainly not unfamiliar with the session, session ID is our respective on the server is a unique flag, this ID string can be generated automatically by PHP, can also be given by us. You may be like me, very concerned about the automatic generation of PHP ID string is how, the probability of conflict, and can not easily be calculated by others, so the following. We download a copy of PHP5.3.6 source code, enter/ext/Session Directory, the function that generated the session ID is located in line 345 of the Session.c file, which is described in detail below. For the sake of understanding, I adjusted the order of some code. PhpapiChar*PHP_SESSION_CREATE_ID (Ps_create_sid_args)/* {{{ */{//These lines define the data required by the hash function and go directly over the ~Php_md5_ctx Md5_context; Php_sha1_ctx Sha1_context;#ifDefined (have_hash_ext) &&!defined (Compile_dl_hash)void*Hash_context;#endifunsignedChar*Digest;intDigest_len;intJ;Char*BUF, *Outid;zval**Array;zval**token;//value used to record $_server[' REMOTE_ADDR ']Char*REMOTE_ADDR =NULL;//a timeval structure to record the current timestamp and the number of millisecondsstructtimeval Tv;gettimeofday (&TV, NULL);//if possible, assign a value to the REMOTE_ADDR, which is represented by a PHP pseudo-code://if (isset ($_server[' remote_addr ') )//{remote_addr = $_server[' remote_addr '];}//Note: There is no in CLI mode ~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*///generate the required session ID, of course, subsequent processing is required ~//The format is:%.15s%ld%ld%0.8f, the meaning of each paragraph is as follows://%.15s remote_addr remote_addr: "" This line is easy to understand.//%ld tv.tv_sec Current timestamp//%ld (long int) tv.tv_usec current number of milliseconds//%0.8f PHP_COMBINED_LCG (tsrmls_c) * 101 Random numbersspprintf (&buf,0,     "%.15s%ld%ld%0.8f", Remote_addr? REMOTE_ADDR:"", Tv.tv_sec, (Long int) tv.tv_usec, PHP_COMBINED_LCG (Tsrmls_c)*Ten);//hashing the value of the BUF string under the face//detecting hash functions in a session configuration/*300 rows: enum{ps_hash_func_md5, PS_HASH_FUNC_SHA1, Ps_hash_func_other};812 line: Php_ini_entry ("Session.hash_function", "0", Php_ini_all,onupdatehashfunc) 738 lines: Static PHP_INI_MH (Onupdatehashfunc)    {.... val = Strtol (New_value, &endptr, 10); if (endptr && (*endptr = = ')}) {/* Numeric value*/PS (Hash_func)= val?1:0; returnSUCCESS; }     ......     ...... The default value of PS (Hash_func) is 0, which is ps_hash_func_md5. */Switch(PS (Hash_func)) {//if it is MD5, the MD5 algorithm is used to hash our buf string.       CasePs_hash_func_md5:php_md5init (&md5_context); Php_md5update (&md5_context, (unsignedChar*) buf, strlen (BUF)); Digest_len= -;  Break; //if it is SHA1, the SHA1 algorithm is used to hash our buf string.       CasePs_hash_func_sha1:php_sha1init (&sha1_context); Php_sha1update (&sha1_context, (unsignedChar*) buf, strlen (BUF)); Digest_len= -;  Break;#ifDefined (have_hash_ext) &&!defined (Compile_dl_hash) CasePs_hash_func_other:if(!PS (Hash_ops)) {Php_error_docref (NULL tsrmls_cc, E_error,"Invalid Session hash function"             );             Efree (BUF); returnNULL; } Hash_context= Emalloc (PS (Hash_ops),context_size); PS (Hash_ops)-Hash_init (Hash_context); PS (Hash_ops)->hash_update (Hash_context, (unsignedChar*) buf, strlen (BUF)); Digest_len= PS (Hash_ops)digest_size;  Break;#endif/* Have_hash_ext *///If there is no hash function, then error, or e_error level, embarrassing ~     default: Php_error_docref (NULL tsrmls_cc, E_error,"Invalid Session hash function");         Efree (BUF); returnNULL;}//Release buf~//embarrassing, that content, content has gone to our hash_context, such as Md5_context, Sha1_context ... Efree (BUF);/*Session.entropy_file gives a path to an external resource (file) that will be used as an additional entropy resource in the session ID creation process. For example, in many Unix systems you can use/dev/random or/dev/urandom. SESSION.ENTROPY_LENGTH Specifies the number of bytes read from the above file. The default is 0 (disabled). If entropy_length this configuration is greater than 0, then:*/if(PS (Entropy_length) >0) {#ifdef php_win32 unsignedCharrbuf[2048]; size_t Toread=PS (entropy_length); if(Php_win32_get_random_bytes (Rbuf, (size_t) toread) = =SUCCESS) {         Switch(PS (Hash_func)) { CasePs_hash_func_md5:php_md5update (&Md5_context, Rbuf, toread);  Break;  CasePs_hash_func_sha1:php_sha1update (&Sha1_context, Rbuf, toread);  Break;# ifDefined (have_hash_ext) &&!defined (compile_dl_hash) CasePs_hash_func_other:ps (hash_ops)-hash_update (Hash_context, Rbuf, toread);  Break; # endif/*Have_hash_ext*/         }     }#else     intFD; FD=Vcwd_open (PS (entropy_file), o_rdonly); if(FD >=0) {unsignedCharrbuf[2048]; intN; intTo_read =PS (entropy_length);  while(To_read >0) {n= Read (FD, RBUF, MIN (To_read,sizeof(RBUF))); if(n hash_update (Hash_context, RBUF, N);  Break;#endif/* Have_hash_ext */} to_read-=N;     } close (FD); }//logic at the end of Entropy_length>0#endif}//or a part of the hash calculation, it seems our hash_final (Digest, hash_context);Efree (Hash_context);  Break;#endif/* Have_hash_ext */}/*Session.hash_bits_per_character allows a user to define how many bits per character are stored when converting binary hash data into a readable format. The possible values are ' 4 ' (0-9,a-f), ' 5 ' (0-9,a-v), and ' 6 ' (0-9,a-z,a-z, "-", ","). */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 being 4, 5, or 6)-using 4 for now"     );}//Digest Our hashed binary data with a string representation in a readable form and placed in the Outid stringOutid = 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;}//back to OutidreturnOutid;} So we can conclude that PHP's default session_id generation algorithm is relatively random, unless the attacker is able to guess the timestamp, the number of milliseconds, and the random number at the back. 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.