Update random ID method to use str_random and not random_bytes

The use of random_bytes in combination with bin2hex was producing a lot of duplicate keys when tested in batches of 10k (anywhere from 2 to 6). The use of str_random yielded no duplicates even at scales of 100k keys that were 8 characters.
This commit is contained in:
Dane Everitt 2017-09-13 23:07:02 -05:00
parent 0e518be6ca
commit a8c4d6afdb
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
14 changed files with 50 additions and 59 deletions

View file

@ -30,8 +30,8 @@ use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
class KeyCreationService
{
const PUB_CRYPTO_BYTES = 8;
const PRIV_CRYPTO_BYTES = 32;
const PUB_CRYPTO_LENGTH = 16;
const PRIV_CRYPTO_LENGTH = 64;
/**
* @var \Illuminate\Database\ConnectionInterface
@ -86,8 +86,8 @@ class KeyCreationService
*/
public function handle(array $data, array $permissions, array $administrative = [])
{
$publicKey = bin2hex(random_bytes(self::PUB_CRYPTO_BYTES));
$secretKey = bin2hex(random_bytes(self::PRIV_CRYPTO_BYTES));
$publicKey = str_random(self::PUB_CRYPTO_LENGTH);
$secretKey = str_random(self::PRIV_CRYPTO_LENGTH);
// Start a Transaction
$this->connection->beginTransaction();

View file

@ -28,7 +28,7 @@ use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
class NodeCreationService
{
const DAEMON_SECRET_LENGTH = 18;
const DAEMON_SECRET_LENGTH = 36;
/**
* @var \Pterodactyl\Contracts\Repository\NodeRepositoryInterface
@ -55,7 +55,7 @@ class NodeCreationService
*/
public function handle(array $data)
{
$data['daemonSecret'] = bin2hex(random_bytes(self::DAEMON_SECRET_LENGTH));
$data['daemonSecret'] = str_random(self::DAEMON_SECRET_LENGTH);
return $this->repository->create($data);
}

View file

@ -83,7 +83,7 @@ class NodeUpdateService
}
if (! is_null(array_get($data, 'reset_secret'))) {
$data['daemonSecret'] = bin2hex(random_bytes(NodeCreationService::DAEMON_SECRET_LENGTH));
$data['daemonSecret'] = str_random(NodeCreationService::DAEMON_SECRET_LENGTH);
unset($data['reset_secret']);
}

View file

@ -29,6 +29,7 @@ use Pterodactyl\Models\Server;
use Illuminate\Database\DatabaseManager;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Services\Nodes\NodeCreationService;
use Pterodactyl\Repositories\Eloquent\ServerRepository;
use Pterodactyl\Repositories\Daemon\ServerRepository as DaemonServerRepository;
@ -83,6 +84,7 @@ class DetailsModificationService
*
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function edit($server, array $data)
{
@ -97,7 +99,7 @@ class DetailsModificationService
(isset($data['reset_token']) && ! is_null($data['reset_token'])) ||
(isset($data['owner_id']) && $data['owner_id'] != $server->owner_id)
) {
$data['daemonSecret'] = bin2hex(random_bytes(18));
$data['daemonSecret'] = str_random(NodeCreationService::DAEMON_SECRET_LENGTH);
$shouldUpdate = true;
}

View file

@ -29,6 +29,7 @@ use Illuminate\Log\Writer;
use Illuminate\Database\DatabaseManager;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Services\Nodes\NodeCreationService;
use Pterodactyl\Contracts\Repository\NodeRepositoryInterface;
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
@ -134,12 +135,13 @@ class ServerCreationService
*
* @throws \Pterodactyl\Exceptions\DisplayException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function create(array $data)
{
// @todo auto-deployment
$validator = $this->validatorService->isAdmin()->setFields($data['environment'])->validate($data['option_id']);
$uniqueShort = bin2hex(random_bytes(4));
$uniqueShort = str_random(8);
$this->database->beginTransaction();
@ -163,7 +165,7 @@ class ServerCreationService
'option_id' => $data['option_id'],
'pack_id' => (! isset($data['pack_id']) || $data['pack_id'] == 0) ? null : $data['pack_id'],
'startup' => $data['startup'],
'daemonSecret' => bin2hex(random_bytes(18)),
'daemonSecret' => str_random(NodeCreationService::DAEMON_SECRET_LENGTH),
'image' => $data['docker_image'],
'username' => $this->usernameService->generate($data['name'], $uniqueShort),
'sftp_password' => null,

View file

@ -37,7 +37,7 @@ class UsernameGenerationService
public function generate($name, $identifier = null)
{
if (is_null($identifier) || ! ctype_alnum($identifier)) {
$unique = bin2hex(random_bytes(4));
$unique = str_random(8);
} else {
if (strlen($identifier) < 8) {
$unique = $identifier . str_random((8 - strlen($identifier)));

View file

@ -29,6 +29,7 @@ use Pterodactyl\Models\Server;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Database\ConnectionInterface;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Services\Nodes\NodeCreationService;
use Pterodactyl\Services\Users\UserCreationService;
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
@ -40,8 +41,6 @@ use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface as DaemonS
class SubuserCreationService
{
const DAEMON_SECRET_BYTES = 18;
/**
* @var \Illuminate\Database\ConnectionInterface
*/
@ -158,7 +157,7 @@ class SubuserCreationService
$subuser = $this->subuserRepository->create([
'user_id' => $user->id,
'server_id' => $server->id,
'daemonSecret' => bin2hex(random_bytes(self::DAEMON_SECRET_BYTES)),
'daemonSecret' => str_random(NodeCreationService::DAEMON_SECRET_LENGTH),
]);
$daemonPermissions = $this->permissionService->handle($subuser->id, $permissions);