Should I remove these use cases of MD5/SHA1 from my program? I have a web app (a register and login system) written already but i am now improving it. One of its design goals was high security.

I have some use cases of md5 and sha1 in it and now i am in doubt if i seriously need to replace them (and with what and how).

I mention that uses here and please tell me if i should replace which cases  why and with what other algorithm (please also mention the necessary bit length that u think is the minimum acceptable). but consider that i don't want to get it too hard; e.g. concatenating the output of sha256 to 128 bits for replacing an md5 invocation seems ok too me (i have asked about that before and seems there is consensus that that is considered secure enough for most practical cases considering i am writing a php app running on real world web servers (I think NSA or hackers can breach via those layers, PHP and web server environment, more easily)), so i don't insist on the latest and top secure standards and don't want to use complicated/bulky algorithms just to reduce a hash output length from 256 to 128!



usage 1:

md5 is used to mix several independent keys to form a single 128 bit key to be used in AES128+HMAC encryption (same key is used for enc and hmac; yes i  know it is considered bad practice, but not really serious so far).

sample code:

$aes-&gt;setKey(pack('H*', md5($GLOBALS['pepper'].$GLOBALS['site_encr_key'].$GLOBALS['client_sess_key'])));




usage 2:

sha1 is used to mix several sources of entropy obtained from client request parameters to be used in the current crypto operation. this extra entropy is stored too and later used in almost all other crypto operations. Neccessary to mention that, all crypto operations have their own newly generated sufficient entropy (at least 128 bits) and the clients' requests entropy is used only as an extra (it can be useful in case some main sources of entropy fail to provide sufficient real entropy for whatever reason or in the rare case that a good standard crypto random generator isn't available in the execution environment).

see my sample code for gathering request entropy:

$request_entropy=sha1(microtime().$pepper.$_SERVER['REMOTE_ADDR'].$_SERVER['REMOTE_PORT'].$_SERVER['HTTP_USER_AGENT'].serialize($_POST).serialize($_GET).serialize($_COOKIE));


this entropy is then combined with the entropy of the past clients' requests and stored in database:

$query="update `site_vars` set `value`=sha1(concat(`value`, '$request_entropy')) where name='entropy'";




usage 3:

sha1 is used in my crypto random number generator function to get a random integer (random numbers generated by this function are then used in other more useful sub-functions, random_bytes and random_string, to generate random strings/tokens and crypto keys in my program).

see the code excerpts for details:

extract(unpack('Nrandom', pack('H*', sha1(openssl_random_pseudo_bytes(4).$entropy.microtime()))));
    return abs($random) % ($max - $min) + $min; 


...

extract(unpack('Nrandom', pack('H*', sha1(fread($urandom, 4).$entropy.microtime()))));
// $urandom is an open file handle to /dev/urandom
    return abs($random) % ($max - $min) + $min;


...

if(function_exists('mcrypt_create_iv') and version_compare(PHP_VERSION, '5.3.0', '&gt;=')) {
    @$tmp16=mcrypt_create_iv(4, MCRYPT_DEV_URANDOM);
     if($tmp16!==false) {
        extract(unpack('Nrandom', pack('H*', sha1($tmp16.$entropy.microtime()))));
        return abs($random) % ($max - $min) + $min;
    }
}


...

extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF).$entropy.microtime()))));
    //mt_rand is only used as a fallback in case other CSPRNGs (openssl_random_pseudo_bytes, /dev/urandom, mcrypt_create_iv) aren't available in the environment
    return abs($random) % ($max - $min) + $min;
Do you know the article If You’re Typing the Letters A-E-S Into Your Code You’re Doing It Wrong? This is basically the same, but with a focus on hashes.

There is a quite important misconception in your system:


you stated "One of its design goals was high security."
and then you start implementing your selfmade algorithms, even stating: "same key is used for enc and hmac; yes i know it is considered bad practice, but not really serious so far"


So, what is your goal here? Actual high security, in a real application? Here a few pointers, if that is actually the goal:


You should probably start by throwing out all those parts, which you designed yourself, and start utilizing proper crypto libraries and the correct primitives. E.g. key derivation functions exist for a reason. 
Randomness (which you call entropy) is nothing to be taken lightly. Just because you implemented a system, you can't figure out how to break yourself, doesn't mean it is secure. Use a cryptographically secure random number generator and be done with it.
Key management is actually a quite critical topic, which is overlooked quite often. E.g. depending on your application, it can be bad if the keys are stored in the same location as user data, etc. If you can utilize a crypto library to handle the key management, all the better.


Your own suggestion of replacing MD5 and SHA-1 with a truncated version of SHA-256 would be a step in the correction direction (better without truncation), as it would be a lie to call anything based on MD5 and SHA-1 highly secure. However, this is just a minor step, and your actual problems go way deeper than that.