Skip to content

Commit 141f9eb

Browse files
committed
feature #15879 Deprecate the SecureRandom class (pierredup)
This PR was merged into the 2.8 branch. Discussion ---------- Deprecate the SecureRandom class | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | | License | MIT | Doc PR | Deprecate the `Symfony\Component\Security\Core\Util\SecureRandom` and encourage the usage of the `random_bytes` function instead Commits ------- f02973a Deprecate the SecureRandom class
2 parents 7236571 + f02973a commit 141f9eb

File tree

16 files changed

+55
-185
lines changed

16 files changed

+55
-185
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"doctrine/common": "~2.4",
2121
"twig/twig": "~1.20|~2.0",
2222
"psr/log": "~1.0",
23-
"symfony/security-acl": "~2.7"
23+
"symfony/security-acl": "~2.7",
24+
"paragonie/random_compat": "~1.0"
2425
},
2526
"replace": {
2627
"symfony/asset": "self.version",

src/Symfony/Bundle/FrameworkBundle/Resources/config/security_csrf.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
</parameters>
1212

1313
<services>
14-
<service id="security.csrf.token_generator" class="%security.csrf.token_generator.class%" public="false">
15-
<argument type="service" id="security.secure_random" />
16-
</service>
14+
<service id="security.csrf.token_generator" class="%security.csrf.token_generator.class%" public="false" />
1715

1816
<service id="security.csrf.token_storage" class="%security.csrf.token_storage.class%" public="false">
1917
<argument type="service" id="session" />

src/Symfony/Bundle/SecurityBundle/Command/UserPasswordEncoderCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,6 @@ private function createPasswordQuestion()
164164

165165
private function generateSalt()
166166
{
167-
return base64_encode($this->getContainer()->get('security.secure_random')->nextBytes(30));
167+
return base64_encode(random_bytes(30));
168168
}
169169
}

src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@
4545
<service id="security.authentication.rememberme.services.persistent"
4646
class="%security.authentication.rememberme.services.persistent.class%"
4747
parent="security.authentication.rememberme.services.abstract"
48-
abstract="true">
49-
<argument type="service" id="security.secure_random" />
50-
</service>
48+
abstract="true" />
5149

5250
<service id="security.authentication.rememberme.services.simplehash"
5351
class="%security.authentication.rememberme.services.simplehash.class%"

src/Symfony/Component/Security/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
`Symfony\Component\Security\Http\Authentication\SimpleFormAuthenticatorInterface` instead
1313
* deprecated `Symfony\Component\Security\Core\Util\ClassUtils`, use
1414
`Symfony\Component\Security\Acl\Util\ClassUtils` instead
15+
* deprecated the `Symfony\Component\Security\Core\Util\SecureRandom` class in favor of the `random_bytes()` function
1516
* deprecated `supportsAttribute()` and `supportsClass()` methods of
1617
`Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface` and
1718
`Symfony\Component\Security\Core\Authorization\Voter\VoterInterface`.

src/Symfony/Component/Security/Core/Tests/Util/SecureRandomTest.php

Lines changed: 13 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,27 @@
1313

1414
use Symfony\Component\Security\Core\Util\SecureRandom;
1515

16+
/**
17+
* @group legacy
18+
*/
1619
class SecureRandomTest extends \PHPUnit_Framework_TestCase
1720
{
1821
/**
1922
* T1: Monobit test.
20-
*
21-
* @dataProvider getSecureRandoms
2223
*/
23-
public function testMonobit($secureRandom)
24+
public function testMonobit()
2425
{
26+
$secureRandom = new SecureRandom();
2527
$nbOnBits = substr_count($this->getBitSequence($secureRandom, 20000), '1');
2628
$this->assertTrue($nbOnBits > 9654 && $nbOnBits < 10346, 'Monobit test failed, number of turned on bits: '.$nbOnBits);
2729
}
2830

2931
/**
3032
* T2: Chi-square test with 15 degrees of freedom (chi-Quadrat-Anpassungstest).
31-
*
32-
* @dataProvider getSecureRandoms
3333
*/
34-
public function testPoker($secureRandom)
34+
public function testPoker()
3535
{
36+
$secureRandom = new SecureRandom();
3637
$b = $this->getBitSequence($secureRandom, 20000);
3738
$c = array();
3839
for ($i = 0; $i <= 15; ++$i) {
@@ -56,11 +57,10 @@ public function testPoker($secureRandom)
5657

5758
/**
5859
* Run test.
59-
*
60-
* @dataProvider getSecureRandoms
6160
*/
62-
public function testRun($secureRandom)
61+
public function testRun()
6362
{
63+
$secureRandom = new SecureRandom();
6464
$b = $this->getBitSequence($secureRandom, 20000);
6565

6666
$runs = array();
@@ -104,11 +104,10 @@ public function testRun($secureRandom)
104104

105105
/**
106106
* Long-run test.
107-
*
108-
* @dataProvider getSecureRandoms
109107
*/
110-
public function testLongRun($secureRandom)
108+
public function testLongRun()
111109
{
110+
$secureRandom = new SecureRandom();
112111
$b = $this->getBitSequence($secureRandom, 20000);
113112

114113
$longestRun = $currentRun = 0;
@@ -133,11 +132,10 @@ public function testLongRun($secureRandom)
133132

134133
/**
135134
* Serial Correlation (Autokorrelationstest).
136-
*
137-
* @dataProvider getSecureRandoms
138135
*/
139-
public function testSerialCorrelation($secureRandom)
136+
public function testSerialCorrelation()
140137
{
138+
$secureRandom = new SecureRandom();
141139
$shift = mt_rand(1, 5000);
142140
$b = $this->getBitSequence($secureRandom, 20000);
143141

@@ -149,44 +147,6 @@ public function testSerialCorrelation($secureRandom)
149147
$this->assertTrue($Z > 2326 && $Z < 2674, 'Failed serial correlation test: '.$Z);
150148
}
151149

152-
public function getSecureRandoms()
153-
{
154-
$secureRandoms = array();
155-
156-
// only add if openssl is indeed present
157-
$secureRandom = new SecureRandom();
158-
if ($this->hasOpenSsl($secureRandom)) {
159-
$secureRandoms[] = array($secureRandom);
160-
}
161-
162-
// no-openssl with custom seed provider
163-
$secureRandom = new SecureRandom(sys_get_temp_dir().'/_sf2.seed');
164-
$this->disableOpenSsl($secureRandom);
165-
$secureRandoms[] = array($secureRandom);
166-
167-
return $secureRandoms;
168-
}
169-
170-
protected function disableOpenSsl($secureRandom)
171-
{
172-
$ref = new \ReflectionProperty($secureRandom, 'useOpenSsl');
173-
$ref->setAccessible(true);
174-
$ref->setValue($secureRandom, false);
175-
$ref->setAccessible(false);
176-
}
177-
178-
protected function hasOpenSsl($secureRandom)
179-
{
180-
$ref = new \ReflectionProperty($secureRandom, 'useOpenSsl');
181-
$ref->setAccessible(true);
182-
183-
$ret = $ref->getValue($secureRandom);
184-
185-
$ref->setAccessible(false);
186-
187-
return $ret;
188-
}
189-
190150
private function getBitSequence($secureRandom, $length)
191151
{
192152
$bitSequence = '';

src/Symfony/Component/Security/Core/Util/SecureRandom.php

Lines changed: 4 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -11,106 +11,23 @@
1111

1212
namespace Symfony\Component\Security\Core\Util;
1313

14-
use Psr\Log\LoggerInterface;
14+
@trigger_error('The '.__NAMESPACE__.'\SecureRandom class is deprecated since version 2.8 and will be removed in 3.0. Use the random_bytes() function instead.', E_USER_DEPRECATED);
1515

1616
/**
1717
* A secure random number generator implementation.
1818
*
1919
* @author Fabien Potencier <fabien@symfony.com>
2020
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
21+
*
22+
* @deprecated since version 2.8, to be removed in 3.0. Use the random_bytes function instead
2123
*/
2224
final class SecureRandom implements SecureRandomInterface
2325
{
24-
private $logger;
25-
private $useOpenSsl;
26-
private $seed;
27-
private $seedUpdated;
28-
private $seedLastUpdatedAt;
29-
private $seedFile;
30-
31-
/**
32-
* Constructor.
33-
*
34-
* Be aware that a guessable seed will severely compromise the PRNG
35-
* algorithm that is employed.
36-
*
37-
* @param string $seedFile
38-
* @param LoggerInterface $logger
39-
*/
40-
public function __construct($seedFile = null, LoggerInterface $logger = null)
41-
{
42-
$this->seedFile = $seedFile;
43-
$this->logger = $logger;
44-
45-
// determine whether to use OpenSSL
46-
if (!function_exists('random_bytes') && !function_exists('openssl_random_pseudo_bytes')) {
47-
if (null !== $this->logger) {
48-
$this->logger->notice('It is recommended that you install the "paragonie/random_compat" library or enable the "openssl" extension for random number generation.');
49-
}
50-
$this->useOpenSsl = false;
51-
} else {
52-
$this->useOpenSsl = true;
53-
}
54-
}
55-
5626
/**
5727
* {@inheritdoc}
5828
*/
5929
public function nextBytes($nbBytes)
6030
{
61-
if (function_exists('random_bytes')) {
62-
return random_bytes($nbBytes);
63-
}
64-
65-
// try OpenSSL
66-
if ($this->useOpenSsl) {
67-
$bytes = openssl_random_pseudo_bytes($nbBytes, $strong);
68-
69-
if (false !== $bytes && true === $strong) {
70-
return $bytes;
71-
}
72-
73-
if (null !== $this->logger) {
74-
$this->logger->info('OpenSSL did not produce a secure random number.');
75-
}
76-
}
77-
78-
// initialize seed
79-
if (null === $this->seed) {
80-
if (null === $this->seedFile) {
81-
throw new \RuntimeException('You need to specify a file path to store the seed.');
82-
}
83-
84-
if (is_file($this->seedFile)) {
85-
list($this->seed, $this->seedLastUpdatedAt) = $this->readSeed();
86-
} else {
87-
$this->seed = uniqid(mt_rand(), true);
88-
$this->updateSeed();
89-
}
90-
}
91-
92-
$bytes = '';
93-
while (strlen($bytes) < $nbBytes) {
94-
static $incr = 1;
95-
$bytes .= hash('sha512', $incr++.$this->seed.uniqid(mt_rand(), true).$nbBytes, true);
96-
$this->seed = base64_encode(hash('sha512', $this->seed.$bytes.$nbBytes, true));
97-
$this->updateSeed();
98-
}
99-
100-
return substr($bytes, 0, $nbBytes);
101-
}
102-
103-
private function readSeed()
104-
{
105-
return json_decode(file_get_contents($this->seedFile));
106-
}
107-
108-
private function updateSeed()
109-
{
110-
if (!$this->seedUpdated && $this->seedLastUpdatedAt < time() - mt_rand(1, 10)) {
111-
file_put_contents($this->seedFile, json_encode(array($this->seed, microtime(true))));
112-
}
113-
114-
$this->seedUpdated = true;
31+
return random_bytes($nbBytes);
11532
}
11633
}

src/Symfony/Component/Security/Core/Util/SecureRandomInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
* Interface that needs to be implemented by all secure random number generators.
1616
*
1717
* @author Fabien Potencier <fabien@symfony.com>
18+
*
19+
* @deprecated since version 2.8, to be removed in 3.0. Use the random_bytes function instead
1820
*/
1921
interface SecureRandomInterface
2022
{

src/Symfony/Component/Security/Core/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
}
1717
],
1818
"require": {
19-
"php": ">=5.3.9"
19+
"php": ">=5.3.9",
20+
"paragonie/random_compat" : "~1.0"
2021
},
2122
"require-dev": {
2223
"symfony/phpunit-bridge": "~2.7|~3.0.0",

src/Symfony/Component/Security/Csrf/Tests/TokenGenerator/UriSafeTokenGeneratorTest.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ public static function setUpBeforeClass()
4444

4545
protected function setUp()
4646
{
47-
$this->random = $this->getMock('Symfony\Component\Security\Core\Util\SecureRandomInterface');
48-
$this->generator = new UriSafeTokenGenerator($this->random, self::ENTROPY);
47+
$this->generator = new UriSafeTokenGenerator(self::ENTROPY);
4948
}
5049

5150
protected function tearDown()
@@ -56,11 +55,6 @@ protected function tearDown()
5655

5756
public function testGenerateToken()
5857
{
59-
$this->random->expects($this->once())
60-
->method('nextBytes')
61-
->with(self::ENTROPY / 8)
62-
->will($this->returnValue(self::$bytes));
63-
6458
$token = $this->generator->generateToken();
6559

6660
$this->assertTrue(ctype_print($token), 'is printable');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy