diff --git a/html/class_passwordRecovery.inc b/html/class_passwordRecovery.inc
index 569fdb62c5a69a91364a288c34ba91e799c79177..1bc84b093c64530fe35db9fa7979101bb102d304 100644
--- a/html/class_passwordRecovery.inc
+++ b/html/class_passwordRecovery.inc
@@ -229,9 +229,8 @@ class standAlonePage {
     $base       = 'ABCDEFGHKLMNOPQRSTWXYZabcdefghjkmnpqrstwxyz123456789';
     $max        = strlen($base) - 1;
     $randomhash = '';
-    mt_srand((double) microtime() * 1000000);
     while (strlen($randomhash) < $len + 1) {
-      $randomhash .= $base{mt_rand(0, $max)};
+      $randomhash .= $base{random_int(0, $max)};
     }
     return $randomhash;
   }
diff --git a/include/class_templateHandling.inc b/include/class_templateHandling.inc
index 54c5f8ec7528cb2b9591fddcb289621f5d744421..8b4789f8ab7fcdff93f4ecef34bf97b87201e6b1 100644
--- a/include/class_templateHandling.inc
+++ b/include/class_templateHandling.inc
@@ -310,7 +310,7 @@ class templateHandling
     $length = 8;
     $chars  = 'b';
     if (count($args) >= 2) {
-      $length = mt_rand($args[0], $args[1]);
+      $length = random_int($args[0], $args[1]);
       if (count($args) >= 3) {
         $chars = $args[2];
       }
@@ -322,11 +322,11 @@ class templateHandling
       switch ($chars) {
         case 'd':
           /* digits */
-          $res .= (string)rand(0, 9);
+          $res .= (string)random_int(0, 9);
           break;
         case 'l':
           /* letters */
-          $nb = mt_rand(65, 116);
+          $nb = random_int(65, 116);
           if ($nb > 90) {
             /* lowercase */
             $nb += 6;
@@ -336,7 +336,7 @@ class templateHandling
         case 'b':
           /* both */
         default:
-          $nb = mt_rand(65, 126);
+          $nb = random_int(65, 126);
           if ($nb > 116) {
             /* digit */
             $nb = (string)($nb - 117);
diff --git a/include/functions.inc b/include/functions.inc
index 0a025c0011db90b2243cd4fe716798ae126405ff..37e51681a89f355568746040b197c4934c1ced55 100644
--- a/include/functions.inc
+++ b/include/functions.inc
@@ -175,25 +175,6 @@ function load_plist ($ldap_available = TRUE)
   return session::global_get('plist');
 }
 
-
-/*!
- * \brief Create seed with microseconds
- *
- * Example:
- * \code
- * srand(make_seed());
- * $random = rand();
- * \endcode
- *
- * \return float a floating point number which can be used to feed srand() with it
- */
-function make_seed()
-{
-  list($usec, $sec) = explode(' ', microtime());
-  return (float) $sec + ((float) $usec * 100000);
-}
-
-
 /*!
  * \brief Debug level action
  *
@@ -1522,8 +1503,7 @@ function gen_uids($rule, $attributes)
       $size = preg_replace('/^.*{id#(\d+)}.*$/', '\\1', $uid);
 
       while (TRUE) {
-        mt_srand((double)microtime() * 1000000);
-        $number = sprintf("%0".$size."d", mt_rand(0, pow(10, $size) - 1));
+        $number = sprintf("%0".$size."d", random_int(0, pow(10, $size) - 1));
         $res    = preg_replace('/{id#(\d+)}/', $number, $uid);
         $ldap->search('(uid='.ldap_escape_f(preg_replace('/[{}]/', '', $res)).')', array('dn'));
         if ($ldap->count() == 0) {
@@ -2482,6 +2462,35 @@ if (!function_exists('ldap_escape')) {
   }
 }
 
+if (!function_exists('random_int')) {
+  // PHP<7, we fallback on openssl_random_pseudo_bytes
+  function random_int($min, $max)
+  {
+    $range = $max - $min;
+    if ($range <= 0) {
+      return $min;
+    }
+
+    $log    = log($range, 2);
+    // length in bytes
+    $nbBytes  = (int) ($log / 8) + 1;
+    // length in bits
+    $nbBits   = (int) $log + 1;
+    // set all lower bits to 1
+    $filter = (int) (1 << $nbBits) - 1;
+    do {
+      $randomBytes = openssl_random_pseudo_bytes($nbBytes, $strong);
+      if (!$strong || ($randomBytes === FALSE)) {
+        throw new Exception('Failed to get random bytes');
+      }
+      $rnd = unpack('C', $randomBytes)[1];
+      // discard irrelevant bits
+      $rnd = $rnd & $filter;
+    } while ($rnd >= $range);
+    return $min + $rnd;
+  }
+}
+
 function ldap_escape_f($str, $ignore = '')
 {
   return ldap_escape($str, $ignore, LDAP_ESCAPE_FILTER);
diff --git a/include/password-methods/class_password-methods-smd5.inc b/include/password-methods/class_password-methods-smd5.inc
index 96d56b3b68a58699a9b53b91e5ee33a7afd6027b..31258f8fc767b840709a0cd2d7522461a8b4edf1 100644
--- a/include/password-methods/class_password-methods-smd5.inc
+++ b/include/password-methods/class_password-methods-smd5.inc
@@ -55,8 +55,7 @@ class passwordMethodsmd5 extends passwordMethod
    */
   function generate_hash($pwd)
   {
-    mt_srand(microtime() * 10000000);
-    $salt0  = substr(pack('h*', md5(mt_rand())), 0, 8);
+    $salt0  = substr(pack('h*', md5(random_int(0, PHP_INT_MAX))), 0, 8);
     $salt   = substr(pack('H*', md5($salt0 . $pwd)), 0, 4);
     $hash   = '{SMD5}'.base64_encode(pack('H*', md5($pwd . $salt)) . $salt);
     return $hash;
diff --git a/include/password-methods/class_password-methods-ssha.inc b/include/password-methods/class_password-methods-ssha.inc
index fa386d7aacf82f5beda9bb6a372d58c9c6504ebc..748c1704c2f89366c8e503e3b96d0cb595cf32cf 100644
--- a/include/password-methods/class_password-methods-ssha.inc
+++ b/include/password-methods/class_password-methods-ssha.inc
@@ -56,12 +56,12 @@ class passwordMethodssha extends passwordMethod
   function generate_hash($pwd)
   {
     if (function_exists('sha1')) {
-      $salt = substr(pack('h*', md5(mt_rand())), 0, 8);
+      $salt = substr(pack('h*', md5(random_int(0, PHP_INT_MAX))), 0, 8);
       $salt = substr(pack('H*', sha1($salt.$pwd)), 0, 4);
       $pwd  = '{SSHA}'.base64_encode(pack('H*', sha1($pwd.$salt)).$salt);
       return $pwd;
     } elseif (function_exists('mhash')) {
-      $salt = mhash_keygen_s2k(MHASH_SHA1, $pwd, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
+      $salt = mhash_keygen_s2k(MHASH_SHA1, $pwd, substr(pack('h*', md5(random_int(0, PHP_INT_MAX))), 0, 8), 4);
       $pwd  = '{SSHA}'.base64_encode(mhash(MHASH_SHA1, $pwd.$salt).$salt);
     } else {
       msg_dialog::display(_('Configuration error'), msgPool::missingext('mhash'), ERROR_DIALOG);
diff --git a/include/simpleplugin/attributes/class_FileAttribute.inc b/include/simpleplugin/attributes/class_FileAttribute.inc
index a7a2455e4f7a3a969dcd7d1b81c4eac6ca2a0c18..422983e62f1c7587829d976842bd79b2b735a69d 100644
--- a/include/simpleplugin/attributes/class_FileAttribute.inc
+++ b/include/simpleplugin/attributes/class_FileAttribute.inc
@@ -354,8 +354,7 @@ class ImageAttribute extends FileAttribute
     $this->setValue($this->inputValue($this->getValue()));
     $id = $this->getHtmlId();
     // Just to be sure the image is not cached
-    srand((double)microtime() * 1000000);
-    $key      = $this->getLdapName().rand(0, 10000);
+    $key      = $this->getLdapName().random_int(0, 10000);
     $display  = '<img id="'.$id.'_img"'.
                 ($this->disabled ? 'disabled="disabled"' : '').
                 ' src="getbin.php?key='.$key.'"'.
diff --git a/setup/class_setupStepChecks.inc b/setup/class_setupStepChecks.inc
index e66d2461f51afcd6e5f91b0e43caad1d0c45f252..bdd7aa8269d3506bbcbc2a052707d33f0b6f725a 100644
--- a/setup/class_setupStepChecks.inc
+++ b/setup/class_setupStepChecks.inc
@@ -95,6 +95,14 @@ class setupStepChecks extends setupStep
     $M = TRUE;
     $basic_checks[] = array('NAME' => $N , 'DESC' => $D , 'RESULT' => $R , 'SOLUTION' => $S , 'MUST' => $M );
 
+    /* Pseudo-random check */
+    $N = _('Checking cryptographically secure pseudo-random integers');
+    $D = _('You must use PHP>=7 or have openssl module activated so that FusionDirectory can generate cryptographically secure pseudo-random integers.');
+    $S = _('Please upgrade to PHP7 or activate openssl module.');
+    $R = (is_callable('random_int') || is_callable('openssl_random_pseudo_bytes'));
+    $M = TRUE;
+    $basic_checks[] = array('NAME' => $N , 'DESC' => $D , 'RESULT' => $R , 'SOLUTION' => $S , 'MUST' => $M );
+
     /* Check for json support */
     $N = msgPool::checkingFor('json');
     $D = _('FusionDirectory requires this module to encode variables for javascript use.');
diff --git a/setup/class_setupStepMigrate.inc b/setup/class_setupStepMigrate.inc
index 6613a3207d19f5b045d13fd88feed1514d9db6cf..a87966cd2e38998eb06aac94dfcccf9675548335 100644
--- a/setup/class_setupStepMigrate.inc
+++ b/setup/class_setupStepMigrate.inc
@@ -471,7 +471,7 @@ class setupStepMigrate extends setupStep
     $ldap = $config->get_ldap_link();
 
     /* Create dummy entry */
-    $name       = 'GOsa_setup_text_entry_'.session_id().rand(0, 999999);
+    $name       = 'GOsa_setup_text_entry_'.session_id().random_int(0, 999999);
     $dn         = 'ou='.$name.','.$config->current['BASE'];
     $testEntry  = array();