Revamp CSecurityManager

I think that CSecurityManager should be updated to take advantage of PHP 5.3 features.

  • Stronger hashing algorithm by default (i.e. whirlpool, sha2), maybe a facility to hash passwords using crypt() with CRYPT_BLOWFISH.

  • Stronger encryption algorithm by default (i.e. rijndael)

  • New random value generator (using openssl_random_pseudo_bytes())

  • Remove the legacy hmac code (just use the built-in hash_hmac() function)

I’ve tinkered with CSecurityManager a few times, but never had a project with a budget large enough to cover the learning curve - I’ve always found this to look attractive, but overly complicated. Or perhaps it just needs better documentation or a working sample of some sort?

I understand why a permission graph is theoretically the most flexible security model, but it is definitely not the easiest to understand, and because of it’s great flexibility, it is also easy to make mistakes. Any ideas for a simpler security model of some sort? Something that is easier to understand and implement.

openssl_random_pseudo_bytes() can have issues on Windows for PHP versions < 5.3.4

If you want to support the Windows platform, I suggest to increase the Yii 2 requirement from PHP 5.3.0 to PHP 5.3.4.


@ekerazha - you can work around this limitation at a minimal cost (small loss of entropy) see

On Windows you are replacing openssl_random_pseudo_bytes() with a non cryptographically secure alternative, aren’t you? Using the time in microseconds (uniqid(), microtime() for hash_hmac()) is not cryptographically secure and relying on Yii::app()->name is not more secure.

You’re right, although in practice it is probably “good enough”. I’m not sure there’s a more reliable way of getting random bytes on windows though, do you know of a solution?

openssl_random_pseudo_bytes() with PHP >= 5.3.4 :D

Otherwise there’s the current mt_rand() solution but it’s not cryptographically secure.

There is this: CryptGenRandom, but I don’t know if it is possible to call it at php-application level, without using PHP’s .NET API or the w32api, which are marked experimental in the php documentation

openssl_random_pseudo_bytes() is the best way to get random bytes on any platform but it depends on the openssl extension being available, which you cann’t rely on:

the problem is what to do when openssl_random_pseudo_bytes() isn’t available.

I don’t think it’s a good idea for the framework to substitute non-crypto-secure random bytes in a class with Secure in its name.

A better approach is to throw an exception if secure platform requirements cannot be met. Perhaps offer the use a way to adopt the insecure option.

But I feel strongly that the user needs to be warned. A framework such as Yii can give the user comfort that she is "doing it right" and we should not do that if the platform cannot meet secure requirements.

I completely agree.

Those are actually good ways to create the illusion of security, which is worse than throwing an exception.

It’s really hard: PHP RFC: Platform and extension-independent API to the system CSPRNG And it’s not just a problem on Windows. The RFC enumerates all the ways to get random bytes from the system CRPRNG that I can find.

I had a discussion earlier this year on php-internals. It seemed they were ok with a new function but I’m stuck trying to find how to read the state of the entropy pool on Solaris, OS X and Windows. Anyway, that’s all way in the future.

Yii framework can help here though I don’t think it can easily solve the problem 100%. A class such as Randomness illustrates what Yii could do to help users by exploring every avenue to get random data. But it should throw an exception when it can’t. Maybe the user could be allowed to configure an insecure option but it should be starkly named so they understand the consequences.

On the other topic, password storage using crypt(), good idea. Yii can help. I’ve helped lots of programmers on Freenode #yii try to use crypt() and they find it very hard, even though the code to use it is so simple. The README of Randomness is so long because of this experience.

The salt for blowfish hashing a password in crypt() does not actually need to be crypto-strong random. No need to drain the entropy pool for that.

I tried many hosting services and I never found a PHP 5.3 installation without openssl module.

However, Yii already requires some modules (i.e. pdo, mcrypt etc.), just add openssl to the required modules. I think this is particularly important for a framework which brands itself as "secure".

If you have mcrypt then you can use mcrypt_create_iv() and don’t need openssl, although that would be preferable.

My experience with Randomness is that people report hosting situations in which it fails. That’s 100% compatible with your experience with hosting services.

Requiring mcrypt and/or openssl is fine. I think that reinforces my argument that Yii should throw an exception when it can’t get random bytes from the OS.

mindplay, are you perhaps talking about RBAC?

if so, i think that’s a discussion worth opening in its own forum thread. CSecurityManager is an different thing, Yii’s crypto api, and i don’t trust it one inch.