I'm using php, but the general question applies to any confirmed cryptographically secure pseudo-random string concatenated with a non-cryptographically secure string.
I know random_bytes generates a cryptographically secure string
I know converting with bin2hex results in a usable cryptographically secure string
But what happens when I shuffle in my own shit non-cryptographically secure strings?
Sample code:
<?php
function randspec($len){
$chars = str_split("!@#$%^&*()_+=-`~<>?:{}|\][;/.,");
$result = "";
for ($i=0; $i<$len; $i++) {
$result .= $chars[mt_rand(0, count($chars)-1)];
};
return $result;
};
$count = 1;
for($i = 0; $i < $count; $i++){
$var_len = mt_rand(2,8);
echo str_shuffle(bin2hex(random_bytes(12)).randspec($var_len));
echo "\r\n";
}
die;
?>
Breakdown for my non-php friends: get a random length between 2-8[mt_rand()], generate a 24 character cryptographically alphanumeric string[bin2hex(random_bytes())], concatenate 2-8 special characters [randspec()], shuffle the special characters into the alphanumeric string [str_shuffle()] - in the entire process, random_bytes() is the only function returning cryptographically secure pseudo-random anything.
My gut tells me that because a large portion of the string is cryptographically secure, and that the addition should only increase complexity, it should only make it harder for a third party to determine the result of the pseudo-random operation - but I also know cryptography is... let's say 'like karma', and I'm no expert. Could the addition of the poorly-generated special characters create a pattern that is (relatively) trivial to predict, or does the quality of the "base" string keep it as random as pseudo-random gets?
Adding an example of Gh0stFish's recommendation for good measure - this is a far better (and simpler) method to generate the same type of varied length string - using this makes my question irrelevant. Open to any input on expanding the possible char set, and whether that's worthwhile, practically.
<?php
function rand_string($len){
$chars = str_split("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()-_=+[]}{\\|;:/?.>,</`~");
$r_string = "";
for($i = 0; $i < $len; $i++){
$r_string .= $chars[random_int(0,82)];
}
return $r_string;
}
$strlen = random_int(26,32);
echo rand_string($strlen);
die;
?>