Ignore Slash while using encryption in codeigniter - php

I have a problem to encrypt/decrypt the email, i just send a link on mail like this
http://www.domain.com/mycontroller/myfunction/McvBsce........etc
The last Segment is actually a encrypted email id, I decrypt this email and update stus in my db when user click on this link.All done right.
Problem: When url like this
http://www.domain.com/mycontroller/myfunction/McvB/sce
It shows 404 error, because slash included in the generated encryption key.How can i ignore the slash while it generate the encryption, that's my main problem, rest are working fine.

You need to use this class, include this file in your applicatio/libraries folder, I had the same issue:
class MY_Encrypt extends CI_Encrypt
{
/**
* Encodes a string.
*
* #param string $string The string to encrypt.
* #param string $key[optional] The key to encrypt with.
* #param bool $url_safe[optional] Specifies whether or not the
* returned string should be url-safe.
* #return string
*/
function encode($string, $key="", $url_safe=TRUE)
{
$ret = parent::encode($string, $key);
if ($url_safe)
{
$ret = strtr(
$ret,
array(
'+' => '.',
'=' => '-',
'/' => '~'
)
);
}
return $ret;
}
/**
* Decodes the given string.
*
* #access public
* #param string $string The encrypted string to decrypt.
* #param string $key[optional] The key to use for decryption.
* #return string
*/
function decode($string, $key="")
{
$string = strtr(
$string,
array(
'.' => '+',
'-' => '=',
'~' => '/'
)
);
return parent::decode($string, $key);
}
}
Credit goes to the codeigniter forum, from where I got this.

Related

Spatie Media Library - Array to string conversion

I am trying to get Spatie Media Library to work, but I have this error:
I really don't know where it comes from, any suggestions?
I'll leave a copy of the portion of the code where the error happens
Str.php
/**
* Replace the given value in the given string.
*
* #param string|string[] $search
* #param string|string[] $replace
* #param string|string[] $subject
* #return string
*/
public static function replaceArray($search, array $replace, $subject)
{
$segments = explode($search, $subject);
$result = array_shift($segments);
foreach ($segments as $segment) {
$result .= (array_shift($replace) ?? $search).$segment;
}
return $result;
}

Warning: openssl_sign() expects parameter 4 to be long

I'm trying to generate a JWT for using apple mapkit js. I found a open source code that generates the token which works fine on my local machine. However, I'm getting the following error when I uploaded to my server.
Warning: openssl_sign() expects parameter 4 to be long
The line that's causing the problem is
if (!openssl_sign($payload, $result, $key, OPENSSL_ALGO_SHA256));
<?php
/**
* Copyright 2018 Includable
* Created by Thomas Schoffelen
*/
namespace Mapkit;
/**
* Class JWT
*
* #package Mapkit
*/
class JWT
{
/**
* Generates a JWT token that can be used for MapKit JS or MusicKit authorization.
*
* #param string $private_key Contents of, or path to, private key file
* #param string $key_id Key ID provided by Apple
* #param string $team_id Apple Developer Team Identifier
* #param string $origin Optionally limit header origin
* #param integer $expiry The expiry timeout in seconds (defaults to 3600)
* #return string|false
*/
public static function getToken($private_key, $key_id, $team_id, $origin = null, $expiry = 3600)
{
$header = [
'alg' => 'ES256',
'typ' => 'JWT',
'kid' => $key_id
];
$body = [
'iss' => $team_id,
'iat' => time(),
'exp' => time() + $expiry
];
if ($origin) {
$body['origin'] = $origin;
}
$payload = self::encode(json_encode($header)) . '.' . self::encode(json_encode($body));
if (!$key = openssl_pkey_get_private($private_key)) {
return false;
}
if (!openssl_sign($payload, $result, $key, OPENSSL_ALGO_SHA256)) { //this is the line that's cause a problem
return false;
}
return $payload . '.' . self::encode($result);
}
/**
* URL-safe base64 encoding.
*
* #param string $data
* #return string
*/
private static function encode($data)
{
$encoded = strtr(base64_encode($data), '+/', '-_');
return rtrim($encoded, '=');
}
}

PHP Where to save OpenSSL encryption key? [duplicate]

This question already has answers here:
Where should I store an encryption key for php?
(5 answers)
Closed 6 years ago.
I'm using this php function to encrypt some strings.
openssl_encrypt();
To generate the encryption key I use
$encryption_key = openssl_random_pseudo_bytes(32);
I also know that this encryption key should be stored somewhere.
The problem is that I don't want to store it in my database, because it could be accessible for hackers.
Where could I also store my keys safely?
P.S. It makes any sense to store encrypted data and used keys in the same database
Here's an example encryption class I created in PHP. The encryption key is stored in this class, which can then be used to decrypt encrypted DB values. Hope this helps.
/**
* Provides basic encryption and decryption of strings and objects.
* Reasonable protection is provided, but you are still responsible
* for sanitizing the source strings or objects prior to use.
*/
class Encrypter {
/**
* This is the global encryption key for the site.
* The longer you make this key, the more secure the encryption
*/
const MASTER_KEY = 'my_amazing_key_of_death';
private $key;
private $cipher;
private $mode;
private $iv;
private $iv_size;
private $key_size;
private $block_size;
public function __construct() {
$this->key = self::MASTER_KEY
$this->cipher = MCRYPT_BLOWFISH;
$this->mode = MCRYPT_MODE_CBC;
$this->block_size = mcrypt_get_block_size($this->cipher);
$this->iv_size = mcrypt_get_iv_size($this->cipher, $this->mode);
$this->key_size = mcrypt_get_key_size($this->cipher, $this->mode);
$this->iv = mcrypt_create_iv($this->iv_size, MCRYPT_RAND);
/**
* if the calculated keysize is shorter than
* they key provided, trim the provided key
* to match its length
*/
if (strlen($this->key) > $this->key_size) {
$this->key = substr($this->key, 0, $this->key_size);
}
}
/**
* Static method alias for string encryption
* #param string $string The string to encrypt
* #return string The encrypted string
*/
public static function enc($string) {
$e = new self;
return $e->encrypt_string($string);
}
/**
* Static method alias for string decryption
* #param string $enc_string The previously encrypted string
* #return string The decrypted/original string
*/
public static function dec($enc_string) {
$e = new self;
return $e->decrypt_string($enc_string);
}
/**
* Encrypt a string
* #param string $string - string to encrypt
* #return string - encrypted string
*/
function encrypt_string($string) {
$enc = mcrypt_encrypt(
$this->cipher,
$this->key,
$string,
$this->mode,
$this->iv
);
$enc = base64_encode($this->iv . $enc);
/**
* replace potentially illegal chars
*/
$enc = strtr($enc, '+/=', '-_,');
/**
* remove unnecessary and ugly trailing commas
*/
$enc = strrev($enc);
if(substr($enc,0,1) == ',') $enc = substr($enc,1);
if(substr($enc,0,1) == ',') $enc = substr($enc,1);
$enc = strrev($enc);
return $enc;
}
/**
* Decrypt an encrypted string and return the original
* #param string $s The string previously encrypted with this class
* #return string The original unencrypted string
*/
function decrypt_string($s) {
$s = strtr($s, '-_,', '+/=');
$s = base64_decode($s);
$this->iv_size = mcrypt_get_iv_size($this->cipher, $this->mode);
$this->iv = substr($s, 0, $this->iv_size);
$data = substr($s, $this->iv_size);
/**
* supress warnings because they happen every time
* IV parameter must be as long as the block size
* yet this still works perfectly
*/
$decrypted = #mcrypt_decrypt($this->cipher, $this->key, $data, $this->mode, $this->iv);
return trim($decrypted);
}
/**
* Serialize an object into an encrypted string
* #throws Exception
* #param object $object
* #return string
*/
function encrypt_object($object) {
if(is_resource($object)) throw new Exception("Cannot encrypt objects of type 'resource'");
$ser = serialize($object);
$enc = base64_encode($ser);
return $this->encrypt_string($enc);
}
/**
* Unserialize an encrypted string back into an object
* #param string $enc
* #return object
*/
function decrypt_object($enc) {
$dec = $this->decrypt_string($enc);
$unenc = base64_decode($dec);
return unserialize($unenc);
}
}

mcrypt warning but still decrypts data

I have a bit of a weird one in this class:
<?php
namespace lib;
/**
* Short description of Crypt
*
* #author xxxx
* #package
*/
class Encryption
{
/**
* Short description of _ch
* handle to the mcrypt resource
*
* #access private
* #var $_ch
*/
private $_ch;
/**
* Short description of __construct
*
* #access public
* #author xxxx
* #param
* #return void
*/
public function __construct( $keyData = NULL, $algorithm = \MCRYPT_RIJNDAEL_256, $mode = MCRYPT_MODE_ECB, $encLibPath = '', $modeDir = '' )
{
$this->_ch = mcrypt_module_open( $algorithm, $encLibPath, $mode, $modeDir );
$vector = mcrypt_create_iv ( mcrypt_enc_get_iv_size( $this->_ch ), \MCRYPT_DEV_URANDOM );
$keySize = mcrypt_enc_get_key_size( $this->_ch );
$key = substr( hash( 'SHA512', $keyData . $keySize ), 0, $keySize );
$x = mcrypt_generic_init( $this->_ch, $key, $vector );
}
/**
* Short description of encrypt
*
* #access public
* #author xxxx
* #param String $str
* #return String $res
*/
public function encrypt( $str )
{
if( !is_string( $str ) )
{
throw new \InvalidArgumentException( 'Attemptig to encrypt data that is not a string' );
return false;
}
$res = mcrypt_generic( $this->_ch, $str );
mcrypt_generic_deinit( $this->_ch );
mcrypt_module_close( $this->_ch );
#var_dump($str,$res);
return $res;
}
/**
* Short description of decrypt
*
* #access public
* #author xxxx
* #param String $str
* #return String $res
*/
public function decrypt( $str )
{
if( !is_string( $str ) )
{
throw new \InvalidArgumentException( 'Attemptig to decrypt data that is not a string' );
return false;
}
82 $res = mdecrypt_generic( $this->_ch, $str );
84 mcrypt_generic_deinit( $this->_ch );
85 mcrypt_module_close( $this->_ch );
#var_dump($str,$res);
return trim( $res);
}
}
when calling this like so:
<?php
$encryption = new \lib\Encryption( 'somekey' );
echo $encryption->decrypt( $safeInfo );
strangle yields:
Warning: mdecrypt_generic(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 82
Warning: mcrypt_generic_deinit(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 84
Warning: mcrypt_module_close(): 90 is not a valid MCrypt resource in E:\htdocs\site\application\lib\encryption.cls.php on line 85
(these lines are shown in the encryption class.)
AND
the expected decrypted string (as in successfully decrypted).
I would be grateful to anyone who might point out why the warnings are raised and why it doesn't seem to affect the outcome.
PS any comments on the effectiveness of the encryption class most welcome.
it looks well
<?php
$encryption = new \lib\Encryption( 'somekey' );
echo $encryption->decrypt(pack("H*", "4a4a564f26618d47536ff35b8a0af3212814a5f0ba635d2cf6f8cd31589042e2"));
_ch lost beacuse mcrypt_module_close( $this->_ch ); in method encrypt()
Maybe you can change __construct and save args only, just create handle ( like _ch ) when you encrypt or decrypt every time.
I'm not good at Mcrypt, so maybe some batter way than mine, but the reason of "valid MCrypt resource" problem is truly mcrypt_module_close
Looks like a namespace issue since you didn't prefix MCRYPT_MODE_ECB in __construct().
This is something to check, but as I can't reproduce, not sure if it's the answer.
You have SHA512 (creating a 512 length key) but the algorythm is expecting a 256 length key. Does it make any difference if you use SHA256? Normally a mismatch in keys should produce garbage, but in this case it may still be working "with side effects".

How can I controll what external web site accesses my web service?

*I'm trying to find out how the "simplest" form of identification can be achieve in order for my partners website to access my web service to retrieve information.*
I want to make sure that only my partner has access to retrieve this information. There is no sensitive data as the data will be shown on my partners website. But I don't want other websites taking advantage of my web service and retrieve data without having access to do so.
I know I can get the IP address using the HttpRequest object, then do a reverse lookup. But not all websites has dedicated ip address and a ISP may use the same IP Address for multiple websites.
I can't see how passing unique identifiers as parameter in the URL can help, because "anyone" can catch that data and use it themselves. But I will use it as an added check.
So the only "secure" way I come up with, is identifying the website accessing my website, then control this against a list on my server.
I would appreciate feedback on what methods would be "most secure".
It's common practice amongst web services to use public/private keys to authenticate API requests. A few example sites that use them: Google, Twitter, EventBrite, Last.FM, GitHub, etc.
These work by having a public or consumer key which is known to everyone. Then each user is given a private or secret key to allow authentication. The cool thing about using this, is since you know exactly who is making the request you have the ability to track activity and potentially throttle number of requests if abused.
The most secure method is to use SSL channel and ask for authentication. If authentication passes then you can give back to client some sort of session key(which can be randomly generated string) and check it on every request.
If your service don't allow to use SSL, then you can try just adding simple username/password authentication for your partners, but in this case if someone intercept your communication they can access your service with same credentials.
Other way is using signatures on every request. For example you can use GPG for this purpose. Your server is holding public keys of all your partners. When partner wants to make query to your server he just signs his request with his private key and upon receiving you will be able to securely verify that this request was sent by particular partner and it's 100% not forged.
Edit
For GPG you need to install PECL module called gnupg. Here is class from our framework that utilize GPG functionality.
class GPG
{
/**
* Encrypt given data to one or more recipients
*
* #param string $string
* #param string|array $encryptKeyID
* #param bollean $armour
* #return string
*/
public static function encrypt($string, $encryptKeyID, $armour = true){
$gpg = new Crypt_GPG();
if(is_array($encryptKeyID)){
foreach($encryptKeyID as $keyId){
$gpg->addEncryptKey($keyId);
}
}
else{
$gpg->addEncryptKey($encryptKeyID);
}
return $gpg->encrypt($string, $armour);
}
/**
* Decrypt given data
*
* #param string $string
* #param string $keyPassword
* #param string $keyID
* #return string
*/
public static function decrypt($string, $keyID, $keyPassword = null){
$gpg = new Crypt_GPG();
$gpg->addDecryptKey($keyID, $keyPassword);
return $gpg->decrypt($string);
}
/**
* Sign given string
*
* #param string $string
* #param string $keyID
* #param string $keyPassword
* #param boolean $mode
* #param boolean $armor
* #return string
*/
public static function sign($string, $keyID, $keyPassword = null, $mode = null, $armor = true){
$gpg = new Crypt_GPG();
if($mode === null){
$mode = Crypt_GPG::SIGN_MODE_CLEAR;
}
$gpg->addSignKey($keyID, $keyPassword);
return $gpg->sign($string, $mode);
}
/**
* Verify signature of given message
*
* #param string $string
* #return boolean
*/
public static function verify($string){
$gpg = new Crypt_GPG();
$signatures = $gpg->verify($string);
if ($signatures[0]->isValid()) {
return true;
}
else{
return false;
}
}
/**
* Encrypt and sign given string to one or more recipients
*
* #param string $string
* #param string|array $encryptKeyID
* #param string $signkeyID
* #param string $signkeyPassword
* #param boolean $mode
* #param boolean $armor
* #return string
*/
public static function encryptAndSign($string, $encryptKeyID, $signkeyID, $signkeyPassword = null, $mode = null, $armor = true){
$gpg = new Crypt_GPG();
if($mode === null){
$mode = Crypt_GPG::SIGN_MODE_CLEAR;
}
$gpg->addSignKey($signkeyID, $signkeyPassword);
if(is_array($encryptKeyID)){
foreach($encryptKeyID as $keyId){
$gpg->addEncryptKey($keyId);
}
}
else{
$gpg->addEncryptKey($encryptKeyID);
}
return $gpg->encryptAndSign($string, $armor);
}
/**
* Decrypt and verify given string
*
* #param string $string
* #param string $keyID
* #param string $keyPassword
* #return array|false
*/
public static function decryptAndVerify($string, $keyID, $keyPassword = null){
$gpg = new Crypt_GPG();
$gpg->addDecryptKey($keyID, $keyPassword);
$result = $gpg->decryptAndVerify($string);
if(empty($result['data']) and empty($result['signatures'])){
return false;
}
if(isset($result['signatures'][0])){
$result['signature'] = $result['signatures'][0]->isValid();
unset($result['signatures']);
}
return $result;
}
}

Categories