Generating URL safe encrypted ids in Codeigniter - php

For encryption of parameters in url, I am using codeigniter encrypt class after extending it. The purpose of extending was to remove /+- from encryption. This was working fine. But after upgrading to PHP 7.1 it is showing deprecation error of mcrypt related methods and documentation is also recommending to use openssl provided in Encryption library. So I implemented it
$this->load->library('encryption');
$this->encryption->initialize(
array('driver' => 'openssl')
);
$this->encryption->encrypt($vendor->vid);
But its generating encrypted ids with / in it.
8da179e79fee45aa3c569d6c54653c99626d57b074fa599f8a109cb0c5f2edb6d7def3f1a6daf5b449d467976a8a32de0819b9af6d84b068f9ec903d41c2bcb9H/eQluY5LUANEDwmCh+/trIvaJu2Bemj2p9J2MnEMII=
How to generate url safe encrypted parameters using openssl in CI ?

A simple solution to this problem is to replace the delimiters that you don't want with another url safe delimiters by extending the core encryption library as you did and use something like this:
function encode($string)
{
$encrypted = parent::encrypt($string);
if ( !empty($string) )
{
$encrypted = strtr($encrypted, array('/' => '~'));
}
return $encrypted;
}
function decode($string)
{
$string = strtr($string, array('~' => '/'));
return parent::decrypt($string);
}

maybe not answering your question but can solve in way obfuscating url safe id
for generate encrypt id just like Youtube watch id i use Hashids Spark for CodeIgniter
https://github.com/sekati/codeigniter-hashids
the purpose of this helper is implementing Hashids to generate hashes (like YouTube or Bitly) from numbers to obfuscate database IDs.
installation just like at instruction i modify the hashids_helper.php at line 20
require_once FCPATH . 'sparks/sk-hashids/' . HASHIDS_VERSION . '/vendor/Hashids.php';
to
require_once FCPATH . 'vendor/Hashids.php'; //according to your Hashids path

Related

How to generate a Token in Symfony 3.4

I have my symfony 2.7 updatet to symfony 3.4.
I used in Symfony 2.7 the function generateToken() to create a token for a file upload task. I found just information about Securely Generating Random Values
for symfony 3.4. But how I can integrate it?
can I use the following Statement?
return bin2hex(random_bytes(32));
I know this might be late but hopefuly it will help somone else because there is no function out-of-the-box from symfony that can be used to generate tokens.
so what i did when i run into this problem is that i used the same token generator that is used by FOSUserBundle wich is this:
public function generateToken()
{
return rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '=');
}
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Util/TokenGenerator.php
and as you can see it uses the random_bytes() function that is recommended in the official documentation of symfony combined with the php function base64_encode() wich is designed to make binary data survive transport through transport layers that are not 8-bit clean, such as mail bodies as explained in the official php documentation and they are using exactiy this example.

can we rely on laravel encryption for future?

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.

How to generate public and private key for API

I want the easy way in order to generate Public / Private key for API, i want a speed class without need of OPENSSL or Any server side installation or third party application.
I tried to look about a Bitcoin Public/Private system generation, but nothing found about it ... and then i tested:
require_once('PHPCoinAddress.php');
$coin = CoinAddress::bitcoin(); coin_info('Bitcoin', $coin);
//////////////////////////////////////////////
function coin_info($name,$coin) {
print 'public (base58): ' . $coin['public'] . "<br>";
print 'private (WIF) : ' . $coin['private'] . "<br>";
}
But this take many times in order to return a result !
Source from here: https://github.com/zamgo/PHPCoinAddress
If u have any easy, speed, secure and unique pair generation solution will be welcome ! Thank's in advance.
Old post, but somebody may find interesting that maybe phpseclib is a solution for such an use case:
From the introduction:
Compatibility
phpseclib is designed to be ultra-compatible. It works on PHP4+ (PHP4,
assuming the use of PHP_Compat) and doesn't require any extensions.
For purposes of speed, mcrypt is used if it's available as is gmp or
bcmath (in that order), but they are not required. Interoperability
phpseclib is designed to be fully interoperable with OpenSSL and other
standardized cryptography programs and protocols.

Decrypting Zend 2 Block Cipher encryption using PHP or Laravel

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.

Validating HMAC using SecurityServiceProvider with Silex

I'm sending an hmac within the URL that I want to valid before allowing users access to the system. There is no user database, so its simply validating the url parameters to verity it was generated by the correct server and users can't change those parameters to access other parts of the system.
I'm wondering if anyone has done something similar with the SecurityServiceProvider. I can do this using the before middleware which is fired after routing and security firewall rules. I'd like to stop this request at the firewall though if possible.
I decided to go with silex's middleware function 'before'. I'm sure this probably isn't the best way to go about this, but my app doesn't have users or authentication so I just need to check the key is correct and return the response. If anyone has any comments on improving this I'd love to hear them.
When an external system is generating a url they must use the shared secret key defined in my config file, and accessible through $app['config']['hmac_key']. the hmac is generated on everything after the hmac in the path. so if ive got sub folders domain.com/folder/hmac/arg1/arg2/arg3. The before filter splits the route at the hmac and builds the path after that.
// Before firing the controller check the hmac matches, otherwise return 403.
$app->before(function (Request $request) use ($app) {
// 40 chars in a sha1 hmac hash
if(!preg_match('/^[0-9a-f]{40}$/i', $request->get('hmac')))
$app->abort(403, "Invalid key.");
// break the route down to the arguments used in hmac
$route = explode('hmac_', $request->get('_route'));
$route = explode('_',$route[1]);
// build the path used to generate hmac
$path = array();
foreach($route as $r)
if($v = $request->get($r))
$path[] = $v;
$path = implode('/', $path);
// Generate hmac hash from path and key
$hmac = hash_hmac("sha1", $path, $app['config']['hmac_key']);
// If the hmac's don't match return 403
if($hmac !== $request->get('hmac'))
$app->abort(403, "Invalid key.");
});

Categories