Wordpress / codeigniter transfer sql database password - mysql

I am on a problem which need a quick solution. I will try to explain it.
I have the table wp_user (from WordPress), where all the members have password encrypted with a wordpress encrypting function. And I have to transfer this table to a new Mysql Database on a new web site working with Codeigniter.
For new members on the new site which works under codeigniter, I use the MD5 function in order to mask password.
But the problem is that the two functions are different, so when an older user try to connect on my new web site, that doesn't work because the passwords don't match ...
So, how I can do for translate the wordpress encrpyting in a normal MD5 password?
Or maybe it's not possible?

Unfortunately you'll have to perform both checks, or just change CI to use the same hashing scheme as WP. That's probably the easier option. If you really want to start using the default CI hashing scheme, you could store both hashes and update the new hash on successful login (when you have the plaintext password).

I'm not familiar with what kind of hashing Wordpress uses for passwords, but I assume that it is secure and irreversible. The hashed passwords cannot be converted to their MD5 equivalent because hashing is a one-way algorithm.
Here is my suggestion for you:
Add a using_md5_flag boolean column to the users table in your new website with default value 0. Copy the passwords over from Wordpress into a column wppassword and also create a column called md5password When users log into the system perform the following code (assumes Datamapper ORM, convert to Active Record if you need to):
$u = new User();
$u->where('username', $this->input->post('username'))->get();
$y = new User();
$y->where('username', $this->input->post('username'));
if($u->using_md5_flag){
/*the flag is 1*/
$y->where('md5password', md5($this->input->post('password')));
$y->get();
if($y->exists()) echo "setting cookie and redirecting to logged in area";
else echo "Wrong credentials!";
}
else{
/*the flag is 0, use wordpress's hashing algorithm (not sure what this is)*/
$y->where('wppassword', wp_hashing_algo($this->input->post('password')));
$y->get();
if($y->exists()){
/*set the using_md5_flag flag so next time they log in it will ignore wp's*/
$y->using_md5_flag = 1;
/*set the new md5 password.*/
$y->md5password = md5($this->input->post('password'));
$y->save();
echo "setting cookie and redirecting to logged in area";
}
else{
echo "Wrong credentials.";
}
}
This code hasn't been tested, I wrote it inside StackOverflow's editor... but It's the method I'd take to perform slow conversion to a more secure hash. Lastly, if you're looking for a really secure hash, check out Bcrypt (phpass), it's more resistant to rainbow table attacks.
Update 1: If you need to use the Phpass library with CodeIgniter, you can find a copy I modified here (I added a constructor). Put this in libraries/Phpass.php You can use the library in your controllers using:
$this->load->library("phpass", array("iteration_count_log2" => 8, "portable_hashes" => FALSE));
$check = $this->phpass->CheckPassword($this->input->post('password'), $u->password);
if($check) /*logged in*/
else /*wrong credentials.*/
When you download the Phpass file it comes with a test.php file which demos how the functions work. I suggest reviewing it.

Related

Shiro - Cannot authenticate using hashed passwords

I'm attempting to use Shiro for Authentication and Authorization for a JSF Web Application I'm building. Unfortunately, I'm still having some difficulty wrapping my head around how it all fits together.
I've been successful (100% using the shiro.ini file) configuring authentication back to a JDBC realm where a test set of credentials are stored. It has worked perfectly for me when credentials are stored in plaintext.
My ultimate goal is to unify an existing credential set in a MySQL database. The passwords are stored as SHA-256 salted hashes. I've spent an entire day reading over the documentation (minus Javadocs) that is available, but I'm still having some difficulty understanding exactly how to set it up.
In an attempt to implement in stages, I've modified my shiro.ini as follows with the intention of simply using SHA-256 hashes:
[main]
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = jdbc/Communicator_dev
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $dataSource
dataSource.resourceRef = true;
jdbcRealm.authenticationQuery = select password from account where site_id = ?
jdbcRealm.userRolesQuery = select user_role from web_roles where site_id = ?
# From https://stackoverflow.com/questions/20742666/shiro-with-jdbc-and-hashed-passwords.
#
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
#configure the passwordService to use the settings you desire
#...
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
#...
# Finally, set the matcher on a realm that requires password matching for account authentication:
jdbcRealm.credentialsMatcher = $passwordMatcher
The actual login logic is programmatic in a page backing bean. Here's the simple test source I'm currently using:
// Create auth token
UsernamePasswordToken token = new UsernamePasswordToken(this.siteID, this.password);
// Get the current subject
Subject currentUser = SecurityUtils.getSubject();
// Attempt to login
try {
currentUser.login(token);
} catch (AuthenticationException e) {
System.out.println("Invalid creds.");
return "";
}
return "authenticated.xhtml?faces-redirect=true";
This code works perfectly with plaintext passwords stored in my RDBMS, but now that I've hashed them, It's failing.
From my understanding of the framework, I believe the problem lies with the AuthenticationToken. I know that I need to use a different token to ultimately implement the Salted Hashes stored in my RDBMS, but I'm confused on how to proceed.
(1) I don't want to reinvent the wheel. Does Shiro have something that does this natively? I've checked out Les' links to PasswordMatcher and PasswordService (from link shiro with jdbc and hashed passwords) but this still isn't clear. Do I need to sub-classingPasswordMatcher?
(2) An architecture question: Who actually calls the doCredentialsMatch(..) method? Is it the Realm during the execution of the login(...) method?
(3) The AuthenticationInfo parameter of the doCredentialsMap(...) method .. Is that supplied by the Realm? Since Realms encapsulate the actual security data, is this an object created from, in my case, the SQL queries that return the password from the RDBMS?
Thank you very much for your time! I'm hoping to be able to contribute to the documentation when I get my head wrapped around it all.
Item 1:
I suspect you may be running into this issue involving the "salt style" parameter of the JdbcRealm which defaults to "NO_SALT". This causes hashing to work but if you're adding a salt to your password the realm will be unable to properly match them.
Here are your steps afterwards:
The default query for a COLUMN based salt style is as follows, "select password, password_salt from users where username = ?". If you cannot use that structure you need to provide a new query via your 'shiro.ini' with a similar structure.
jdbcRealm.authenticationQuery=select password, salt_column_here from users where username = ?
Here is a related question.
Item 2: Yes, the realm calls the doCredentialsMatch(..) method.
Item 3: Yes, the realm supplies the AuthenticationInfo to the doCredentialsMatch(..) method.

Why does my Perl script fail to connect to the database?

I have a Perl script which retrieves data from MySQL Database. this is the code:
sub startSession{
my $self = shift;
my $dsn = "dbi:".$self{platform}.":".$self{database}.":".$self{host}.":".$self{port};
print "$dsn\n" ;
$self{dbHandle} = DBI->connect($dsn,$user,$password);
}
I have provided every information from an external file. I get the error message
DBI connect('dbname:**.**.**.**:3306','',...) failed: Access denied for user 'root'#'dbserver' (using password: NO) at line 89
Can't call method "prepare" on an undefined value at at line 97
I am very sure the root can connect from any host and the password is also correct.
First, your immediate problem, is as #Sinan Ünür says, that you need to change $self{platform} to $self->{platform}, etc.
Your second immediate problem is that it appears you're getting $user and $password from nowhere (they are not passed to the function, so they are undefined unless they are global variables), which would explain the using password: NO part of the error. Maybe those should be $self->{user} and $self->{password}?
You should considering put this at the top of your module, at least during development, to automatically catch errors like these:
use warnings qw(all);
use strict;
But I'd also comment, that from a design perspective, you really ought to treat DSNs as opaque strings. Each database has its own DSN format. So if you ever want to target a different database, you'll need a different DSN format. Or, possibly, someday MySQL will use a different format (it already has two). Either way, it'll be much easier to change it one place, in a configuration file, than to track down each place you concatenate the various pieces together.
The key part of the warning that I see is "using password: NO". Check that the password is being set properly.
Presumably, $self is a hashref, not a plain hash, and you don't have warnings on. So, turn them on, and use $self->{platform} etc.

MySQL credentials/hosts variables best practices

I want to know what is the best practice or what is recommended to do when a variables are created for MySQL credentials/host.
define('HOST', 'localhost');
// etc..
mysql_connect(HOST, // etc...
vs
$host = 'localhost';
// etc..
mysql_connect($host, // etc...
For both you can easily check what are the declared variables or constants and maybe can find what are the value easily. I have code that multiple users can share and use.
What is the best way to protect these variables?
Here's few solutions
1) You give each user a user and password and each user has their permissions in the database (only select, or insert ect..). So in your code you simply include a db.config.php so all the variables are set. It does not really matter if the user echo the variables since they use their own.
2) you can give a common username/pass for the database and then encode the file (either using custom encoding, zend optimizer or ioncube and unset the variables. Here's a sample code:
// file mysql_connect.php
$link = mysql_connect("localhost", "mysql_user", "mysql_password")
or die("cannot connect to database : " . mysql_error());
// then this file is encoded so nobody can view it.
3) At some point, someone, somehow will be able to find this information. I would simply recommend to trust your user (assuming these are developers)
At some point in your code you will have to hardcode this kind of information, the important thing is to keep it in only one place to promote maintanability.
However, as you are worried about security I suggest you to check this: Convert PHP file to binary

combining django ORM with direct database access for a complex app?

Sorry, if this is a newbie question.
We're building an analytics application, with different components. The visualization and web app is in Django, backend connecting drivers are written using PHP, and various analytics are written in python (precomputed, django is only responsible for rendering).
All these components access and update the same database (mysql). The tables were created by Django ORM, but are updated by Python scripts (mysqldb) and PHP as required.
Are there any unseen downsides to this approach of mixing django ORM access and direct database access? For the python component, we could use ('from django.core.management import setup_environ'), but its more efficient to have direct control over SQL statements. Is there a better design approach that we should be aware of?
The only downside is we can think of, is the added complexity to future changes to the database/models.py, but that's something we can live with.
Thanks!
Answering this myself.
We have this working fine since several weeks. The only downside of course, is that if we make changes to models.py (using django ORM), we have to tweak PHP code by hand, which would be expected.
For authenticated users, the PHP code uses data from auth_user to authenticate incoming connections. The exact use of password + salt to generate hash is documented in other posts, see What is the format in which Django passwords are stored in the database?.
Edit: #Josh asked for the PHP snippet, here it is:
// ASSUMES YOU HAVE django username and password from web form POST request
// GET THE HASH + SALT FOR THIS USER
$query = "SELECT password FROM auth_user WHERE username = '$_POST[email]' LIMIT 1 ";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result);
list($algo,$salt,$pass) = explode('$',$row['password']);
// RE-HASH PASSWORD from POST request
$hash = sha1($salt . $_POST['password']);
$hash = "sha1$$salt$$hash";
// GET HASH FROM DATABASE TO COMPARE
$query = "SELECT username FROM auth_user WHERE password = '$hash' LIMIT 1";
$result = mysql_query($query) or die(mysql_error());

Postfix + MySQL ENCRYPT(), How does it verify the password with randomizing salt?

I've implemented my mail server as dictated here.
It works perfectly fine. My curiousity revolves around entering users into the database and authenticating them
Running:
INSERT INTO users (email, password) VALUES ('sales#example.com', ENCRYPT('password'));
Multiple times will give a different hash for the encrypted password as its utilizing a random salt. I.e. If I enter sales#example.com three times with the same password each hash is different...
My question to this is, how is it that the Postfix server can actually authenticate the password when a user logs in via a mail client?
There isn't any problem per say as it works fine, more just to satisfy my curiosity so I can fully understand whats going on behind the scenes to properly authenticate the encrypted password.
Postfix compares the password from the database to a new encrypt done with the salt(password from db).
to encrypt:
update user set password = ENCRYPT('1234') where id = 1
to check password:
SELECT u.* FROM user u where u.email ='admin#dominio.com'
and ENCRYPT('1234', u.password) = u.password
Read man crypt: it returns the salt in the first two chars of the return value.
So the salt is not lost, you can compare the encrypted string to the result of crypt( 'pass', $first_two_chars_of_encrypted_value ).
You must use ENCRYPT('pass','salt') to force a salt, otherwise the salt is lost forever and you have no way of recovering it. Fairly pointless function without it. It's a terrible function to use, though, because the security is so minimal; use PASSWORD() or OLD_PASSWORD() instead.
ENCRYPT() uses the system crypt(), which may use all or only the first 8 characters, must be printable 7-bit ascii, generally uses 1 round of a DES-based hash, and is completely unportable. Avoid it.