Any Security holes in this php code? - php

i found the structure of the following code on this very site, and i'm now using it, so i just want to know if there are any security holes that can be exploited from this code, if it can be improved or if at all there are any deprecated elements i shouldn't use.
i'll be using the following for OTP Code through SMS.
<?php
function randomCode(){
$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$Code = array();
$alphaLength = strlen($alphabet) - 1;
for ($i = 0; $i < 6; $i++){
$n = rand(0, $alphaLength);
$Code[] = $alphabet[$n];
}
return implode($Code);// turn array into string
}
echo randomCode();
?>
Beginner

upd.
I rewrote the code a bit:
function randomCode(){
$alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$Code = "";
$alphaLength = strlen($alphabet) - 1;
for ($i = 0; $i < 6; $i++){
$Code .= $alphabet[rand(0, $alphaLength)];
}
return $Code;
}
echo randomCode();
upd2.
This would be secure, if you block this code after 3 wrong attempts.

Yes, you should not use insecure random number generators for security purposes.
From http://php.net/manual/en/function.rand.php
Caution This function does not generate cryptographically secure
values, and should not be used for cryptographic purposes. If you need
a cryptographically secure value, consider using
openssl_random_pseudo_bytes() instead.
This is because the rand will generate predictable values, the attacker only needs to figure out the seed used.
See here: Predicting the output of PHP's rand()

use more charecters like # or # and lowercase letters in your $alphabet var.

Related

Generate save activation key as product key

I am trying to create a function which creates a random String. This String should consist of letters (only caps) and numbers. It will be used to activate a product. So the user has to type it into a text field.
So far I found the following function:
function random_str($length, $keyspace = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'){
$pieces = [];
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$pieces []= $keyspace[random_int(0, $max)];
}
return implode('', $pieces);
}
I do not have that much experience with random functions. So is there anything to improve or would you suggest a different function?
To generate a cryptographically secure random string (which I would recommend for an activation key), I would rather use openssl_random_pseudo_bytes
You can find the doc here and some useful informations in that thread (for example, how to get a random string with 0-9A-Z characters rather than just 0-9A-F).
As of PHP7.0 you could also use random_bytes, which is also cryptographically secure.
readable - base64_encode(random_bytes($lenght ) ); shorter
readable longer - bin2hex(random_bytes($lenght ) );
To make with wanted length use substr
Use rand function instead of 'random_int'
function random_str($length, $keyspace =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'){
$pieces = [];
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$pieces []= $keyspace[rand(0, $max)];
}
return implode('', $pieces);
}
echo random_str('50');
// Output //
P7V55MYPQJGRNQ8W0VW7TRKBDK2B7NXWUT20F0P6J5Y7W63X20

Long digit random number create algorithm

I want to create long digit random number in php but there is one question on my mind. What is the best way for performance.
For example first option that i thought.
rand(10000,99999)
but i don't know how would performance be with this. how would it be if even longer?
so i think of this
$randomNumber=rand(10,99).rand(10,99).rand(10,99)...
is it more efective than first one?
Thank you.
You can use MD5() or if you are using mysql then UUID(). otherwise rand(10000,99999) is OK .
Try this
function RandomNumber()
{
$size = '15';
$randomnumber = '';
for ($i = 0; $i < $size ; $i++) {
$randomnumber .= rand(0,9);
}
return $randomnumber;
}
$random = RandomNumber();
echo $random;
rand(10000,99999)
use of above function is pragmatically and logically very good advise than other options

generating thousands unique unpredictable serial numbers

Hi I want to generate thousands of unique unpredictable serials, so I wrote this function
function generate_serials($count){
$serials = array();
$token = '8uhf7+-=??/\/';
for($i = 1; $i <= $count; $i++){
$hash = sha1(md5( $token . ( time() + (432 * 1000) ) ));
$serial = '';
for($j = 0; $j < 12; $j++){
if($j == 4 || $j == 8) $serial .= '-';
$serial .= $hash[rand(0, 39)];
if(in_array($serial, $serials)){
$serial = '';
$j = 0;
}
}
$serials[] = $serial;
}
return $serials;
}
I have few problems about this approach.
I don't know why, but I don't trust this. (As I always think my solutions and I are stupid) is there any problem with this?
another problem is with performance that it takes about 20-30 seconds, Is it natural or I made a mess?
UPDATE
Oh sorry guys
the problem of performance was that the counter for inner loop was the same name as outer loop ..my mistake! :D
Your solution is overcomplicated. It doesn't have to be that way. If you have OpenSSL installed look into openssl_random_pseudo_bytes
Alternatively you could use mt_rand and hash like so:
$serial = hash('sha512', mt_rand());
However mt_rand does not generate cryptographically secure values so it may not be as unpredictable as you wish.

Random Code Overkill?

I have some code I am using
function genCode ($entropy=1) {
$truCde = "";
$indx = 0;
$leng = 30*$entropy;
while ($indx < $leng) {
$code = "";
$length = 100*$entropy;
$index = 0;
while ($index < $length) {
$code .= rand();
$index++;
}
$index = 0;
while ($index < $length) {
$code = sha1($code);
$index++;
}
$truCde .= $code;
$indx++;
}
$finalCode = sha1(rand()) . hash("sha256",$truCde . md5($entropy*rand()));
$finalCode .= sha1(md5(strlen($finalCode)*$entropy));
return hash (
"sha256",
sha1($finalCode) . sha1(md5($finalCode)) . sha1(sha1($finalCode))
);
}
to generate a random code for e-mail verification. Is there code that takes less time to generate random codes. It takes about 1-2 seconds to run this code, but I am looking to shave .7 seconds off this because the rest of the script will take longer.
That's massive overkill. Calling rand() repeatedly isn't going to make the code "more random", nor will using random combinations of SHA and MD5 hashes. None of that complexity improves the verification codes.
An improvement that would make a difference would be to use mt_rand() in preference to rand(). The Mersenne Twister pseudo RNG is much stronger than most default rand() implementations. The PHP documentation hints that rand() may max out at 215 meaning you can only generate 32,768 unique verification codes.
Other than that, a single hash call will do.
sha1(mt_rand())
(You don't even really need to call a hash function as the unpredictability of your codes will come from the random number generator, not the hash function. But hash functions have the nice side effect of creating long hex strings which "look" better.)
If you just want to generate random strings to test that someone has access to an email address, or something like that, I would throw out that code and use something a lot more straightforward. Something like the following would likely do.
function genCode () {
$chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
$returnValue = '';
for ($i = 0; $i < 20; $i++) {
$returnValue .= $chars[mt_rand(0, 35)];
}
return $returnValue;
}
You can hash the return value if you want, but I don't know what the point would be other than to obfuscate the scheme used to come up with the random strings.

PHP code for generating decent-looking coupon codes (mix of letters and numbers)

For an ecommerce site I want to generate a random coupon code that looks better than a randomly generated value. It should be a readable coupon code, all in uppercase with no special characters, only letters (A-Z) and numbers (0-9).
Since people might be reading this out / printing it elsewhere, we need to make this a simple-to-communicate value as well, perhaps 8-10 characters long.
Something like perhaps,
AHS3DJ6BW
B83JS1HSK
(I typed that, so it's not really that random)
$chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$res = "";
for ($i = 0; $i < 10; $i++) {
$res .= $chars[mt_rand(0, strlen($chars)-1)];
}
You can optimize this by preallocating the $res string and caching the result of strlen($chars)-1. This is left as an exercise to the reader, since probably you won't be generating thousands of coupons per second.
Try this:
substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, 10)
Why don't keep it simple?
<?php
echo strtoupper(uniqid());
?>
Always returns 13 character long uppercased random code.
You can use the coupon code generator PHP class file to generate N number of coupons and its customizable, with various options of adding own mask with own prefix and suffix. Simple PHP coupon code generator
Example:
coupon::generate(8); // J5BST6NQ
http://webarto.com/35/php-random-string-generator
Here you go.
function randr($j = 8){
$string = "";
for($i=0;$i < $j;$i++){
srand((double)microtime()*1234567);
$x = mt_rand(0,2);
switch($x){
case 0:$string.= chr(mt_rand(97,122));break;
case 1:$string.= chr(mt_rand(65,90));break;
case 2:$string.= chr(mt_rand(48,57));break;
}
}
return strtoupper($string); //to uppercase
}
If there are no security requirements for these, then you don't really need randomly generated codes. I would just use incremental IDs, such as those generated by whatever RDBMS you use. Optionally, if you have different types of coupons, you could prefix the codes with something, e.g.:
CX00019 QZ0001C
CX0001A QZ0001D
CX0001B QZ0001E
Alternately, you could even use dictionary words in the coupon, as such coupon codes are easier to remember and faster for users to type. Companies like Dreamhost use these for their promo codes, e.g.:
Promo60
NoSetupFee
YELLOWGORILLA82
Some of these are obviously human-created (which you might want to have the option of), but they can also be generated using a dictionary list. But even if they are randomly-generated nonsense phrases, the fact that the characters follow a logical pattern still makes it much more user-friendly than something like R7QZ8A92F1. So I would strongly advise against using the latter type of coupon codes just on the basis that they "look cool". Your customers will thank you.
$size = 12;
$string = strtoupper(substr(md5(time().rand(10000,99999)), 0, $size));
function generateCouponCode($length = 8) {
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$ret = '';
for($i = 0; $i < $length; ++$i) {
$random = str_shuffle($chars);
$ret .= $random[0];
}
return $ret;
}
you can find a lot of function in php rand manual
http://php.net/manual/en/function.rand.php
i like this one
<?php
//To Pull 8 Unique Random Values Out Of AlphaNumeric
//removed number 0, capital o, number 1 and small L
//Total: keys = 32, elements = 33
$characters = array(
"A","B","C","D","E","F","G","H","J","K","L","M",
"N","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9");
//make an "empty container" or array for our keys
$keys = array();
//first count of $keys is empty so "1", remaining count is 1-7 = total 8 times
while(count($keys) < 8) {
//"0" because we use this to FIND ARRAY KEYS which has a 0 value
//"-1" because were only concerned of number of keys which is 32 not 33
//count($characters) = 33
$x = mt_rand(0, count($characters)-1);
if(!in_array($x, $keys)) {
$keys[] = $x;
}
}
foreach($keys as $key){
$random_chars .= $characters[$key];
}
echo $random_chars;
?>
$length = 9;
$code = (strtoupper(substr(md5(time()), 0, $length)));
Just Write
$voucher_no = date('ymd') . rand(1000, 9999);
while(SapItem::where('voucher_no', $voucher_no)->exists()){
$voucher_no = date('ymd') . rand(1000, 9999);
}
Output: 2204171447

Categories