I am building an iOS app for an already existing web application I created. The web app uses laravel and sentry to encrypt passwords. New users have to be able to be created from the iOS app.
The server that the web app talks to is written in php but does not use laravel or sentry.
The only sentry function I need is the one they use to encrypt passwords.
What function does sentry use to hash passwords? I am talking about Cartalyst\Sentry\Hashing\NativeHasher
I need to be able to duplicate this function and use it in a separate php file.
i've found this link : https://github.com/cartalyst/sentry/blob/master/src/Cartalyst/Sentry/Hashing/NativeHasher.php
and this code is what you want probably:
public function hash($string)
{
// Usually caused by an old PHP environment, see
// https://github.com/cartalyst/sentry/issues/98#issuecomment-12974603
// and https://github.com/ircmaxell/password_compat/issues/10
if (!function_exists('password_hash')) {
throw new \RuntimeException('The function password_hash() does not exist, your PHP environment is probably incompatible. Try running [vendor/ircmaxell/password-compat/version-test.php] to check compatibility or use an alternative hashing strategy.');
}
if (($hash = password_hash($string, PASSWORD_DEFAULT)) === false) {
throw new \RuntimeException('Error generating hash from string, your PHP environment is probably incompatible. Try running [vendor/ircmaxell/password-compat/version-test.php] to check compatibility or use an alternative hashing strategy.');
}
return $hash;
}
Related
So I have made an encryption middleware in laravel that encrypts data using the following code
public function handle($request, Closure $next)
{
return response()->json(encrypt($response->content()),$response->status());
}
I ran the command
php artisan:generate key
So now I'm trying to decrypt this data from flutter I tried using encrypt package in flutter but still no luck in making it work.
I feel the problem is the following:
1- The key used in encryption ni laravel is APP_KEY right it is in the format base64:random string this should be my key without base64?
2- Flutter encryption package needs IV I keep trying to set it from the key but still failing would really appreciate any help.
I have never done this between laravel and dart, but i have between two laravel apps.
// bits stolen from the laravel EncryptionServiceProvider.php
if (Str::startsWith($key = env('OTHER_APPS_API_APP_KEY'), 'base64:')) {
$key = base64_decode(substr($key, 7));
}
$encrypter = new Encrypter($key, config('app.cipher')); // probably AES-256-CBC
// decrypt the data
$encrypter->decrypt($theDataToDecrypt);
If you can find a library in dart that supports the same ciper you shoud be able to do the same
from laravel docs
Application Key The next thing you should do after installing Laravel
is set your application key to a random string. If you installed
Laravel via Composer or the Laravel installer, this key has already
been set for you by the php artisan key:generate command.
Typically, this string should be 32 characters long. The key can be
set in the .env environment file. If you have not renamed the
.env.example file to .env, you should do that now. If the application
key is not set, your user sessions and other encrypted data will not
be secure!
What I know about application key is: If the application key is not set, generally I do get an exception.
How do this random string help to secure the session?
What are the other uses of this application key?
If I use the same application key everywhere (like staging, production etc..) does it make the application less secure?
what are some best practices for this key
As we can see its used in EncryptionServiceProvider:
public function register()
{
$this->app->singleton('encrypter', function ($app) {
$config = $app->make('config')->get('app');
// If the key starts with "base64:", we will need to decode the key before handing
// it off to the encrypter. Keys may be base-64 encoded for presentation and we
// want to make sure to convert them back to the raw bytes before encrypting.
if (Str::startsWith($key = $this->key($config), 'base64:')) {
$key = base64_decode(substr($key, 7));
}
return new Encrypter($key, $config['cipher']);
});
}
So every component that uses encryption: session, encryption (user scope), csrf token benefit from the app_key.
Rest of the questions can be answered by "how encryption" (AES) works, just open up Encrypter.php, and confirm that Laravel uses AES under the hood and encodes the result to base64.
Further more we can see how its all done by using tinker:
➜ laravel git:(staging) ✗ art tinker
Psy Shell v0.8.17 (PHP 7.1.14 — cli) by Justin Hileman
>>> encrypt('Hello World!')
=> "eyJpdiI6ImgzK08zSDQyMUE1T1NMVThERjQzdEE9PSIsInZhbHVlIjoiYzlZTk1td0JJZGtrS2luMlo0QzdGcVpKdTEzTWsxeFB6ME5pT1NmaGlQaz0iLCJtYWMiOiI3YTAzY2IxZjBiM2IyNDZiYzljZGJjNTczYzA3MGRjN2U3ZmFkMTVmMWRhMjcwMTRlODk5YTg5ZmM2YjBjMGNlIn0="
Note: I used this key: base64:Qc25VgXJ8CEkp790nqF+eEocRk1o7Yp0lM1jWPUuocQ= to encrypt Hello World!
After decoding the result we get (you can try decode your own cookie with session):
{"iv":"h3+O3H421A5OSLU8DF43tA==","value":"c9YNMmwBIdkkKin2Z4C7FqZJu13Mk1xPz0NiOSfhiPk=","mac":"7a03cb1f0b3b246bc9cdbc573c070dc7e7fad15f1da27014e899a89fc6b0c0ce"}
to understand above json (iv, value, mac) you need to understand AES:
https://en.wikipedia.org/wiki/Advanced_Encryption_Standard
Best practices for application key
do store it in .env file only
do not store it in app.php, in fact in any git tracked file
do not change it unless you really want to
invalidate sessions/cookies (user logout)
invalidate password reset tokens
invalidate signed urls
Obvious Note: Changing application key has no effect on hashed passwords since hashing algorithms do not require encryption keys.
We are building application where we need to store a data encrypted in database and instead of using MySql AES_ENCRYPT and AES_DECRYPT we are plaining to use laravel's inbuilt encrypt & decrypt functions.
Is it will be future proof as we don't want to loose data for future updates.
First of all, nothing is truly "future proof." In fact, we're on the verge of current encryption being rendered obsolete by quantum computing, making all current encryption methods very much not future proof.
Does Taylor have any plans of changing it in the foreseeable future? Maybe, maybe not, but the only real way of knowing is to ask him directly. He's quite active on Twitter and in other venues, so as far as business owners go, he's pretty approachable. He's also a generally nice person, so don't be afraid to ping him.
But let's take a look at the code:
public function encrypt($value, $serialize = true)
{
$iv = random_bytes(16);
// First we will encrypt the value using OpenSSL. After this is encrypted we
// will proceed to calculating a MAC for the encrypted value so that this
// value can be verified later as not having been changed by the users.
$value = \openssl_encrypt(
$serialize ? serialize($value) : $value,
$this->cipher, $this->key, 0, $iv
);
if ($value === false) {
throw new EncryptException('Could not encrypt the data.');
}
// Once we get the encrypted value we'll go ahead and base64_encode the input
// vector and create the MAC for the encrypted value so we can then verify
// its authenticity. Then, we'll JSON the data into the "payload" array.
$mac = $this->hash($iv = base64_encode($iv), $value);
$json = json_encode(compact('iv', 'value', 'mac'));
if (! is_string($json)) {
throw new EncryptException('Could not encrypt the data.');
}
return base64_encode($json);
}
That's the main encrypt() function from master in the repository, and from the looks of it, it's not likely to be changed too much without completely rewriting it. And while Laravel doesn't really follow the SemVer versioning spec, it does generally follow an internally consistent versioning scheme, making the most likely times for it to change are at the whole number and first-decimal change (i.e. - 5.4 to 5.5 or 5.5 to 6.0).
However, it's worth noting that it's actually accessed via contracts and the service provider pattern (so the only time the class is actually directly referenced is in its associated ServiceProvider class). This means that you can use this one for now and if a breaking change is introduced in the future, you can copy this version into your own encryption class, replace the reference in config/app.php to Illuminate\Encryption\EncryptionServiceProvider to your new encryption service provider, and you've now preserved that method and can use it throughout your application, without making any other changes to your application.
On a bit of a side note, you can also consider writing an "encryption converter" if you find you do need to change algorithms (such as if your original algorithm is insecure) by using the old system's decrypt method to decrypt everything, then re-encrypt it all with the new system and storing it again. The application would then just use the new algorithm going forward.
I was asked to create an API using the Laravel framework on an existing Web application. The web application uses the Zend 2 Block Cipher encryption to encrypt user password. The previous developer who developed the site has already moved on and I need to create a service to verify the user's password in the API. The problem is I can't crack Zend's encryption. I even tried using the PHP mcrypt function but I'm getting this error.
mcrypt_decrypt(): Size of key is too large for this algorithm
This is a bit odd but is there anyway I can decrypt Zend's encryption using just plain PHP? Or is there a work around here? I can't change the current web application as it is being used.
Here is the sample code of the encryption:
use Zend\Crypt\BlockCipher;
class Encryption {
private $_cipher = null;
public function __construct(){
$this->_cipher = BlockCipher::factory('mcrypt',array('algo'=>'aes'));
$this->_cipher->setKey('fltjXW05820D[1(Z5SknJBZ12goBbyK<*271biqT5"j$WvA2JCycgA"{UIe6qJ2');
}
public function encrypt($plainText){
return $this->_cipher->encrypt($plainText);
}
public function decrypt($enctyptedData){
return $this->_cipher->decrypt($enctyptedData);
}
}
Any advice by the experts?
Thank you in advance. Sorry I'm a beginner in Laravel and Zend.
A requirement for the deployment of a PHP application I am working on is that is uses FIPS-140 validated cryptographic modules.
The customer has specifically flagged up that "PHP utilizes a cryptographically weak random number generator to produce session ID information" and cited this report: http://berlin.ccc.de/~andreas/php-entropy-advisory.txt
I have advised them on how to set session.entropy_length and session.hash_function to increase entropy, but they have not accepted this, specifically requiring that we use a FIPS-140 compliant RNG.
I'm not certain on the difference between the hash function and the RNG, so am struggling to respond. Can anyone suggest a way of using a FIPS-140 compliant function to generate session ids within php?
We're running PHP 5.4.16 on Windows + SQL Server, in case it matters.
Thanks
A requirement for the deployment of a PHP application I am working on is that is uses FIPS-140 validated cryptographic modules.
My condolences. A headache is to FIPS-140 what a drop of morning dew is to the ocean.
I'm not certain on the difference between the hash function and the RNG, so am struggling to respond. Can anyone suggest a way of using a FIPS-140 compliant function to generate session ids within php?
If you're using ext/mcrypt, mcrypt_create_iv() uses Windows' CryptGenRandom API which should be FIPS-140 compliant. (Or, at minumum, it should be possible to setup that way.) That function is the only good thing about mcrypt, and exists separatef from libmcrypt.
If you're using OpenSSL, and compiled OpenSSL in FIPS mode, you can similarly use openssl_random_pseudo_bytes() and it should use a FIPS-compliant generator.
Finally, if you upgrade to PHP 7+ and use random_bytes(), so long as Windows is FIPS-140 compliant, you're golden.
The hash function really doesn't matter here. You want to use a secure source and that's it. Hashing it doesn't buy you anything. If you're forced to use a hash function, use one of the SHA2 family hash functions (SHA256, SHA384, or SHA512) approved for use in FIPS-140 compliant software.
Session Generator that should pass FIPS-140 audits
<?php
/**
* #return string
*/
function session_id_fips140()
{
if (is_callable('random_bytes')) {
return session_id(bin2hex(random_bytes(32)));
}
if (is_callable('mcrypt_create_iv')) {
return session_id(bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)));
}
if (is_callable('openssl_random_pseudo_bytes')) {
return session_id(bin2hex(openssl_random_pseudo_bytes(32)));
}
// Fail closed. Maybe install random_compat?
throw new Exception("No suitable PRNG is available on the current system!");
}
Usage:
<?php
ini_set('session.
if (!isset($_COOKIE['PHPSESSID'])) {
session_id_fips140();
}
session_start();