I have a database from an application with a lot of users I would like to migrate to a new mediawiki 1.24.0 installation.
My problem is to hash and match the passwords.
So I have a Password like :special:3tvn09gpt4v5zu7ß3809mzn and now I edited the LocalSettings.php by adding:
$wgPasswordConfig['special'] = array(
'class' => 'SpecialPassword',
);
I put a SpecialPassword.php file inside /includes/password/ and it contains
class SpecialPassword extends ParameterizedPassword {
public function crypt( $plaintext ) {
$this->args = array();
$this->hash = $this->SpecialHash( $plaintext );
}
function SpecialHash( $plaintext ) {
// .. //
}
}
wehre hash( $plaintext ) returns the hashed password.
But when I try to test I get
Class 'SpecialPassword' not found in .../includes/password/PasswordFactory.php on line 118`
So is this the right way to do it, and how to load my class?
i had to add my class to the wgAutoloadLocalClasses
Related
Good day.
Using the encryption library in CodeIgniter, I can encrypt any string by using $this->encryption->encrypt('string'); and that is the easiest way to encrypt the string. However, this method is not the safest way to secure the data I think so I decided to use salt for better encryption. I read the documentation provided by Codeigniter about the Encryption Library and I don't really understand how encryption and salt really work.
Here is my code for encryption.
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class MyEncryption {
//please do not change or delete this saltKey. "5948356750394856"
private static $saltKey = "5948356750394856";
// ================
public $CI;
function __construct()
{
$this->CI =& get_instance();
$this->CI->load->library('encryption');
}
public function encryptStringWithSalt($string) {
$p = $this->CI->encryption->encrypt(
$string,
$this->encryption_config()
);
return $p;
}
public function decryptEncryptedStringWithSalt($encryptedString) {
return $this->CI->encryption->decrypt(
$encryptedString,
$this->encryption_config()
);
}
private function encryption_config(){
$key = $this->CI->config->item('encryption_key');
$hmac_key = $this->CI->encryption->hkdf(
$key,
'sha512',
MyEncryption::$saltKey,
10,
'authentication'
);
return array(
'cipher' => 'aes-128',
'mode' => 'CTR',
'key' => MyEncryption::$saltKey,
'hmac' => true,
'hmac_digest' => 'sha224',
'hmac_key' => $hmac_key
);
}
}
As we can see, I created a function that gathers the encryption configuration. Inside that function, I have called the method $this->CI->encryption->hkdf() to create hmac key as what documentation example says. For clarification, here are the parameters of hkdf() method and the provided example.
Additionally, the return keyword with array data in encryption_config() function is the 2nd parameter of encrypt() method in encryption library. I used encryption->hkdf() because of the parameter salt on it. I am new in encryption with salt in Codeigniter so I'm really struggling on how to achieve this kind of encryption. So what I've done is that the code above really works for encryption and decryption but for some reason I don't really understand why the return value is different from the normal encryption. The difference is, this encryption method $this->encryption->encrypt("some string"); returns but using the code above returns .
Though I can decrypt that symbolic character, this will not save this encrypted data to the database with the data type of varchar but instead, it will be saved as a normal character or string. Here are the data saved to database .
My questions are, I am doing correctly? if not, what is the proper way to implement this library with salt? I want the encrypted data as normal text not a symbolic character, can I achieve that goal? and lastly? is there anyway to check the string if the string is encrypted or not? Please help me. I spend days for this problem only. I watch youtube tutorial related for encryption but no luck.
Okay. after searching on the internet I found a solution without using this CI encryption Library. I achieved my goal by using this code
<?php
defined('BASEPATH') or exit('No direct script access allowed');
/**
*
*/
class SaltEncryption
{
public $CI;
function __construct()
{
$this->CI =& get_instance();
}
public function encrypt($data){
$password = "any string";
$iv = substr(sha1(mt_rand()), 0, 16);
$password = sha1($password);
$salt = sha1(mt_rand());
$saltWithPassword = hash('sha256', $password.$salt);
$encrypted = openssl_encrypt(
"$data", 'aes-256-cbc', "$saltWithPassword", null, $iv
);
$msg_encrypted_bundle = "$iv:$salt:$encrypted";
return $msg_encrypted_bundle;
}
public function decrypt($msg_encrypted_bundle){
$password = "any string";
$password = sha1($password);
$components = explode( ':', $msg_encrypted_bundle );
if (
count($components)=== 3 &&
strlen($components[0]) === 16
) {
$iv = $components[0];
$salt = hash('sha256', $password.$components[1]);
$encrypted_msg = $components[2];
$decrypted_msg = openssl_decrypt(
$encrypted_msg, 'aes-256-cbc', $salt, null, $iv
);
if ( $decrypted_msg === false )
return false;
$msg = substr( $decrypted_msg, 41 );
return $decrypted_msg;
}
return false;
}
}
I am trying to use encryption library in Codeigniter 3.1.3 in HMVC provided by Wiredesignz. I even tried initializing the encryption library with my custom settings as below as it didn't work with default:
$this->load->library('encryption');
$this->encryption->initialize(
array(
'cipher' => 'aes-256',
'driver' => 'openssl',
'mode' => 'ctr'
)
);
$this->load->module('site_security');
$str = "12345";
$encrypted_str = $this->encryption->encrypt($str);
echo "encrypted_str: ".$encrypted_str; //works fine gives me encrypted string.
$decrypted_str = $this->encryption->decrypt($encrypted_str);
echo "<br>decrypted_str: ".$decrypted_str; // always gives me empty string
I used the encrypt method to successfully encrypt a string but I can't decrypt it, it always gives me empty string. I also set the $config['encryption_key'] to a 32 characters string in config/config.php file.
Codeigniter by default uses $config['encryption_key'] which you can find it in the config file, for the cryptographic process!
so for decrypting it, you have to first have this key! then you can decrypt it as follows:
$this->load->library('encrypt');
$encrypted_password = 'what you want to descript, put that here';
$key = 'secret-key-in-config';
$decrypted_string = $this->encrypt->decode($encrypted_password, $key);
and after that, you can encrypt it again!
First set encryption_key in your config file.
$config['encryption_key'] = 'something';
Second set load library in your controller.
public function test()
{
$this->load->library('encryption');
$plain_text = 'This is a plain-text message!';
$ciphertext = $this->encryption->encrypt($plain_text);
// Outputs: This is a plain-text message!
echo $this->encryption->decrypt($ciphertext);
}
If you have an existing code base with users and their passwords, how can you change the password encoder and have users' passwords update?
In other words, let's say all user passwords are in MD5 and you want to transition to PBKDF2. The common strategy is to simply re-hash the password whenever the user logs in next.
However, I'm not sure how to do this in Symfony. Would it be done in the login controller? Or is there a way to do it in the EncoderInterface object?
Check out this blog... seems like this is what you're looking for...
How to change the way Symfony2 encodes passwords
You need to extend MessageDigestPasswordEncoder class, overwrite its methods and copy that class to the Security folder in your bundle (create one if not exist)
Check out the following example of how to extend MessageDigestPasswordEncoder
use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder as BaseMessageDigestPasswordEncoder;
class MessageDigestPasswordEncoder extends BaseMessageDigestPasswordEncoder
{
private $algorithm;
private $encodeHashAsBase64;
public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
{
$this->algorithm = $algorithm;
$this->encodeHashAsBase64 = $encodeHashAsBase64;
$this->iterations = $iterations;
}
protected function mergePasswordAndSalt($password, $salt)
{
if (empty($salt)) {
return $password;
}
return $salt.$password; // or do whatever you need with the password and salt
}
public function encodePassword($raw, $salt)
{
// this is the original code from the extended class, change it as needed
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; $i++) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
}
After you have your class ready update your config.yml
# app/config/config.yml
# ...
parameters:
security.encoder.digest.class: Ens\TestBundle\Security\MessageDigestPasswordEncoder
So I'm trying to create a Blowfish encrypted password with a salt using a User class that I have created, which in turns extends an overall database object that uses Late Static Bindings to CRUD from my database. Anyway, I'm trying to get this darn thing to encrypt the password before I call the create() method and inset it onto my database but each time when I do put the information in the form it goes to a blank 'update.php' screen (update.php has all my isset($_POST[]) calls for all my forms) and nothing gets uploaded to my database. Here's the code so far...
Code in update.php
if (isset($_POST["createAdmin"])) {
$user = new Users();
$user->password = $user->password_encrypt($_POST['new_password']);
$user->username = $_POST['new_username'];
$user->first_name = $_POST['first_name'];
$user->last_name = $_POST['last_name'];
if($user->create()) {
$_SESSION['new_admin_message'] = $user->password;
redirect_to("../public/admin/manage_admin.php");
}
else {
$_SESSION['new_admin_message'] ="Admin didn't create successfully";
redirect_to("../public/admin/manage_admin.php");
}
}
Code in user.php (the user class)
<?php
require_once(LIB_PATH.DS.'database.php');
class Users extends DatabaseObject {
protected static $table_name="users";
protected static $db_fields = array('id', 'username', 'password', 'first_name', 'last_name');
public $id;
public $username;
public $password;
public $first_name;
public $last_name;
public static function password_encrypt($password) {
$hashed_format = "2y$10$"; // Tels PHP to use Blowfish with a "cost" of 10
$salt_length = 22; // Blowfish salts should be 22-characters or more
$salt = generate_salt($salt_length);
$format_and_salt = $hash_format . $salt;
$hash = crypt($password, $format_and_salt);
return $hash;
}
private function generate_salt($length) {
// Not 100% unique, not 100% random, but good enoguh for a salt
// MD5 returns 32 characters
$unique_random_string = md5(uniqid(mt_rand(), true));
// Valid caracters for a solt are [a-zA-Z0-9./]
$base64_string = base64_encode($unique_random_string);
// But not '+' which is valid in base64 encoding
$modified_base64_string = str_replace('+', ".", $base64_string);
//Truncate string to the correct length
$salt = substr($modified_base64_string, 0, $length);
return $salt;
}
There's a couple other methods in the class that aren't important for this particular problem. I'm relatively new to OOP and PHP in general so any help would be greatly appreciated. If you could leave a short description on how you fixed the problem that would be awesome too. Thanks!!
There are three things wrong with your code:
You cannot refer to a normal method from a static method. In order for your code to work you also have to make the generate_salt method static.
You use the wrong format variable ($hash_format should be $hashed_format) when concatenating the format and salt.
Your format is wrong. Look at the documentation. The blowfish format is:
$[algo]$[difficulty]$[salt]$
Your format comes out to be:
[algo]$[difficulty]$[salt]
So, change your method to something like this:
public static function password_encrypt($password) {
$format = '$2y$10$'.$this->generate_salt(22).'$';
return crypt($password, $format);
}
Another thing, which is not technically "wrong" but is not a good thing, is your salt method. You should generate your salt from a cryptographically stronger source, such as using the mcrypt extension or, if you are on *nix, even grabbing it from /urandom or /random. Creating a "random" string by calling a mish-mash of functions, and ending up with something that looks random enough, is not a good idea.
The best thing you could do is to use the password library that comes with PHP. It will handle all the password hashing for you, and will protect you from yourself. If you have PHP <5.5.0 then you should use the compatibility library.
In other words, you should change your code to this:
public static function password_encrypt($password) {
return password_hash($password, PASSWORD_BCRYPT, ['cost' => 10]);
}
I cannot get an encryption class to work (it's in a seperate file in the classes folder). The code for the class is:
class SymmetricCrypt
{
// Encryption/decryption key.
private static $msSecretKey = "Hello";
// The initialisation vector.
private static $msHexaIv = "c7098adc8d6128b5d4b4f7b2fe7f7f05";
// Use the Rijndael Algorithm.
private static $msCipherAlgorithm = MCRYPT_RIJNDAEL_128;
public static function Encrypt($plainString)
{
$binary_iv = pack("H*", SymmetricCrypt::$msHexaIv);
// Encrypt source.
$binary_encrypted_string = mcrypt_encrypt(SymmetricCrypt::$msCipherAlgorithm, SymmetricCrypt::$msSecretKey, $plainString, MCRYPT_MODE_CBC, $binary_iv);
// Convert $binary_encrypted_string to hexadeciaml format.
$hexa_encrypted_string = bin2hex($binary_encrypted_string);
return $hexa_encrypted_string;
}
public static function Decrypt($encryptedString)
{
$binary_iv = pack("H*", SymmetricCrypt::$msHexaIv);
// Convert string in hexadecimal to byte array.
$binary_encrypted_string = pack("H*", $encryptedString);
// Decrypt $binary_encrypted_string,
$decrypted_string = mcrypt_decrypt(SymmetricCrypt::$msCipherAlgorithm, SymmetricCrypt::$msSecretKey, $binary_encrypted_string, MCRYPT_MODE_CBC, $binary_iv);
return $decrypted_string;
}
}
This is how I am calling the class:
require_once 'classes/symmetric_crypt.php';
$sc = new SymmetricCrypt();
$password = "password";
$ec_password = $sc->Encrypt($password);
... insert into database.
If I echo the contents of $password, then it displays "password". If I echo $ec_password, it returns nothing.
I've used it before on a different project on a different server. Could it be something server-related? Any other ideas?
Thanks,
Adrian
Works here.
Two notes:
Your initialization vectors should not be reused. Otherwise, it gets easier to find the encryption key (see WEP).
Like premiso saids, you should not stored store passwords as decryptable strings. Use salted hashes with strong hash functions (not MD5!).