We help IT Professionals succeed at work.

php md5 decrypt

webdork
webdork asked
on
i've inherited a database with an encrypted password field. I'm moving the data to MS SQL Server. i'd like to decrypt the pw field or use the field as encrypted in SQL Server and have it function in a classic ASP environ.

Which is the best solution and how would I proceed?
Comment
Watch Question

Armand GSenior Developer
CERTIFIED EXPERT
Commented:
The best way you can do it is to decrypt the field first in MySQL and then when importing to SQL Server, you need to use the VARCHAR/VARBINARY datatype (but VARBINARY is better) for that field in SQL Server. You can then use this guideline which I find extremely helpful for the Encryption/Decryption procedures:

http://msdn.microsoft.com/en-us/library/ms179331.aspx

Author

Commented:
thanks for the quick response. that article looks like an encryption method. can you point me at a decrypt method?

Author

Commented:
perhaps this is not an md5 hash.

I see that 123456
encrypts to XitᅠEg

hope that helps.
Dave BaldwinFixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014

Commented:
MD5 is not considered 'decryptable', it is a one-way function.  http://en.wikipedia.org/wiki/MD5  Here is an ASP routine to generate MD5: http://www.freevbcode.com/ShowCode.Asp?ID=2366
Dave BaldwinFixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014

Commented:
'123456' to 'XitÔæ†Eg' is not MD5.  

From http://en.wikipedia.org/wiki/MD5 :

"An MD5 hash is typically expressed as a 32-digit hexadecimal number."  It will always be that size no matter what the input is.
Armand GSenior Developer
CERTIFIED EXPERT

Commented:
Okay thanks DaveBaldwin for the MD5 information. So, going back to MySQL we can still use that field to SQL Server by using VARBINARY data type and then using HASHBYTES function to decrypt the imported field data inside SQL Server.

For step by step guide, use this reference:
http://redfinsolutions.com/blog/replicate-mysqls-md5-function-sql-server-2005-using-hashbytes
Armand GSenior Developer
CERTIFIED EXPERT

Commented:
Correction: It's not decryption, it should be replicate. There is no decryption for MD5.
For Example:

Ysx%udis0x (From MySQL database)
123456 (Actual data from SQL Server) --> using HASHBYTES --> Ysx%udis0x (From SQL Server DB)

then you compare Ysx%udis0x = Ysx%udis0x (both from MySQL and SQL Server), if match then you have a successful operation for whatever is used.

Aurelian ConstantinProgrammer-analyst

Commented:
Unless you have the source code that used the inherited database, you cannot "guess" the formula that encrypts the password, resulting the string in password column.

Definitely, it's not MD5, wich always outputs a 32 bit length string, no matter of input string length.

Sample:

MD5("123456") = "e10adc3949ba59abbe56e057f20f883e"

Open in new window

Bad news I'm afraid. Not only my predecessors are right, and it's not MD5, also without the original encryption function i really don't see how could you use this data even if you've just replicated it.

It looks like DES or 3DES encryption to me, but you have no seed , nothing as far as your post says.
You will end up with a database full of codes and no way to encrypt passwords supplied during your users authentication for comparison.

Nothing has been said about the application that interfaces with the database.  What language is this interface?  If it's a web interface, there's a good chance that there's fairly easily accessible source code...

Author

Commented:
thanks crazedsanity. The web application is written in php. I have access to all the files. Can you give me a hint on some phrases to search for to find the encryption routine?
I'd search for "login" or "auth".  Remember to do case-insensitive searching... if it's a Linux server, the command line is your friend.  Go into whatever directory the application lives, and "grep" can find it:

grep -iRn login *

Open in new window

grep -iRn auth *

Open in new window


Tracing the code isn't always easy, but a good place to start is the login form: open the page in your browser and view the HTML to figure out what script is actually handling the login (the "action" part of the form)... using Firefox with the Web Developer Toolbar extension really helps here, as it can display form information without having to view source.

Once you have the login script, just follow where the credentials are getting passed.  Either the code in the called script will encrypt the values, or some class/object will do it.  Watch for the "include" and "require" statements to see what scripts are being added into the mix.
If you have a lot of problems finding it, consider posting the source of the login page.  That would allow us to point you in the right direction.

Author

Commented:
Here are the includes:

//============================================================================================//
// (A) LOAD COMPONENTS
//============================================================================================//
include ("includes/isellstart.php");
include('includes/smarty/libs/Smarty.class.php');
include ("includes/checkout/checkout_functions.php");
include ("includes/product_functions.php");

if( $_GET['b'] == "logout_final"){ $block = $_GET['b']; }else{ $block = "default"; }
if( $_POST['b'] == "login" || $_POST['b'] == "new_acct"){ $block = $_POST['b']; }
That's pretty nasty looking code.  I'd suggest putting it in [ code ] [ / code ] tags (same syntax, but without spaces), but it doesn't look like that's necessary for this particular chunk of code.

So, follow the "$block" variable.  Is there code below this part?  

Author

Commented:
Here is the whole login page.  Its a 3rd party cart code. They no longer support their product.
<?php  

//edited 05-24-10 08.47.58 AM
/*============================================================================================//
 iSell 3.0 (tm) 2006
 
 (TOC) for isell/login.php updated on 08/15/06
 
(A) LOAD COMPONENTS
(B) CART CLOSED?
(C) START SMARTY
(D) TEMPLATES OR RWTHEMES & CART ACTIONS


//============================================================================================*/

//============================================================================================//
// (A) LOAD COMPONENTS
//============================================================================================//
include ("includes/isellstart.php");
include('includes/smarty/libs/Smarty.class.php');
include ("includes/checkout/checkout_functions.php");
include ("includes/product_functions.php");

if( $_GET['b'] == "logout_final"){ $block = $_GET['b']; }else{ $block = "default"; }
if( $_POST['b'] == "login" || $_POST['b'] == "new_acct"){ $block = $_POST['b']; }


$errors = "";

//============================================================================================//
// (B) CART CLOSED?
//============================================================================================//
// See if we are open
is_cart_closed();

//============================================================================================//
// (C) START SMARTY
//============================================================================================//
$smarty = new Smarty;
if(!CART_CACHING){
	$smarty->force_compile = "true"; // <-- for debugging only.
	}//if
$smarty->assign("prev_checked", "CHECKED");
$smarty->assign("new_checked", "");

//============================================================================================//
// (D) VALIDATE FORM
//============================================================================================//

// If already logged in redirect to account page
if($_SESSION['AccountLoggedIn'] && $block != "logout_final"){ 
$relay = "account.php?".SESS_SID;
header("Location: $relay");
exit;
}

switch ( $block )
{
    

// PREVIOUS ACCOUNT LOGIN   
    
    case "login":
    
    	
		$errors = accountLogin($_POST['prev_email'], $_POST['prev_password']);
				
			if($errors){
				// Error - Show errors
				$smarty->assign("errors", $errors);
				$action = "login_errors";
			}else{
				// Success - Redirect to Account Page
				header("Location: account.php?".SESS_SID);
			}
				    	
        break;

  

 
// NEW ACCOUNT LOGIN 
        
    case "new_acct":
    
    	$error_cnt=0;
    	$smarty->assign("prev_checked", "");
		$smarty->assign("new_checked", "CHECKED");
    	
    	// See if login is present?
    	if(!$_POST['new_email']){ $errors = "Email Address is Required.<br />"; $error_cnt++; }
    	if(!$_POST['new_password']){ $errors .= "Password is Required.<br />"; $error_cnt++; }
    	// Validate email
    	//if(!validate_email($_POST['new_email'])){ $errors .= "Email Address is not valid format.<br />"; $error_cnt++; }
    	// Check password length
    	if(strlen($_POST['new_password']) < 5){ $errors .= "Password Needs to be at Least 5 characters.<br />"; $error_cnt++; }
    	// Check password characters
    	if(preg_match('/[^A-Za-z0-9]/', $_POST['new_password'])){ $errors .= "Password Needs to be made up of alphanumeric characters only.<br />"; $error_cnt++; }
    	
    	if(!$error_cnt){
    		// See if login already exists?
    		if(checkAccount($_POST['new_email'], "", "new")){ $errors .= "An account with the email you entered already exists.<br />"; $error_cnt++; }
    	} // <-- if no errors
    	
    	if(!$error_cnt){
    	// if no errors, then add user to db and proceed
    	
    		if(addAccount($_POST['new_email'], $_POST['new_password'])){
    	
    		$_SESSION['AccountEmail'] = $_POST['new_email']; //<-- set accountemail as session var
			$_SESSION['AccountLoggedIn'] = "true"; //<-- set session var saying we are logged in
			
			if ($_POST['in_checkout']) { 
			$_SESSION['CheckingOut'] = "true";
			$smarty->assign("checking_out", "true");
			}//<-- set if customer is new and checking out.
			
			$relay = "account.php?".SESS_SID."&b=edit";
			header("Location: $relay");
			
			
    	
    		} // <-- if addAccount returned no error
    	    	    	
    	}else{
    	
    		// Error - Show errors
			$smarty->assign("errors", $errors);
    	
    	} // <-- if no errors (end)
        
        break;

	case "logout_final":
	
	// Clear values in all Account session vars
	
	$_SESSION['BillToFirstName'] = "";
	$_SESSION['BillToLastName'] = "";
	$_SESSION['BillToName'] = "";
	$_SESSION['BillToCompany'] = "";
	$_SESSION['BillToAddress1'] = "";
	$_SESSION['BillToAddress2'] = "";
	$_SESSION['BillToCity'] = "";
	$_SESSION['BillToState'] = "";
	$_SESSION['BillToStateOther'] = "";
	$_SESSION['BillToZip'] = "";
	$_SESSION['BillToCountry'] = "";
	$_SESSION['BillToEmail'] = "";

	$_SESSION['ShipToFirstName'] = "";
	$_SESSION['ShipToLastName'] = "";	
	$_SESSION['ShipToName'] = "";
	$_SESSION['ShipToCompany'] = "";
	$_SESSION['ShipToAddress1'] = "";
	$_SESSION['ShipToAddress2'] = "";
	$_SESSION['ShipToCity'] = "";
	$_SESSION['ShipToState'] = "";
	$_SESSION['ShipToStateOther'] = "";
	$_SESSION['ShipToZip'] = "";
	$_SESSION['ShipToCountry'] = "";
	$_SESSION['dayPhone'] = "";
	
	$_SESSION['AccountEmail'] = ""; //<-- set accountemail as session var
	$_SESSION['AccountLoggedIn'] = ""; //<-- set session var saying we are logged in
	$_SESSION['AccountType'] = ""; //<-- account type, will be used later for type-based pricing
	$_SESSION['AccountID'] = ""; //<-- account type, will be used later for type-based pricing
	
	$relay = "login.php?".SESS_SID;
	header("Location: $relay");
	
	
	break;


        
        
    default:
         //< -- remove later
    break;
}





//============================================================================================//
// (D) TEMPLATES OR RWTHEMES
//============================================================================================//

if(CART_RW_THEMES){  // <-- are we gonna use rw theme engine

include ("includes/rw_functions.php");
$smarty->template_dir = "themes";
include("includes/smarty_assigns.php"); // <-- Get commonly used variables
$template = $rw_settings['themeshortname']."/contents/index.html";
$login_page = $smarty->fetch("prefs/login.tpl");
$smarty->assign("content", $login_page);
$smarty->display($template);


}else{ // <--not using rw theme engine

include("includes/smarty_assigns.php"); // <-- Get commonly used variables
$template = CART_THEME."/login.tpl";

$smarty->assign("prev_email", $_POST['prev_email']);
$smarty->assign("new_email", $_POST['new_email']);
$smarty->assign("errors", $errors);
$smarty->assign("action", $block);
$smarty->display($template);


} // <-- if end rw check




?>

Open in new window

Well... following the path of "$block", I hit a dead-end around line 67, which calls a function "accountLogin()".   So the next step is to find that.  Search for
function accountLogin(

Open in new window


There's a very good chance that this function definition will give all the answers needed.  Feel free to paste the source of the file if necessary.

Author

Commented:
Ok thanks. I've got some "honey dos" (required) right now, back in 30 min.

WD
Dave BaldwinFixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014

Commented:
You need to find addAccount, that's where the encoding will be.:

addAccount($_POST['new_email'], $_POST['new_password'])
Dave BaldwinFixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014

Commented:
I mean the addAccount routine, not the word...

Author

Commented:
I think this??
//=================================//
// + ACCOUNT ADD
//=================================//
function addAccount($email, $pw){

	$query = "INSERT INTO isell3_accounts(email, password) VALUES('".$email."', '".encryptPassword($pw, PASSWORD_KEY)."')";
	if($results=mysql_query($query)){
	$_SESSION['AccountID'] =  mysql_insert_id();
	$_SESSION['BillToEmail'] =  $email;
	return true;
	}else{
	return false;
	}

Open in new window

Author

Commented:
I think this is the key?

define ("PASSWORD_KEY", 'dogs love sh1p');
Dave BaldwinFixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014

Commented:
I think you're right.  Now you need to find the encryptPassword() routine...

Author

Commented:
Isn't that it 2 posts above?

Author

Commented:
Maybe this:
//======================================//
// + ENCRYPT/DECRYPT
//======================================//

function encryptPassword($password, $key){
      // Encryption Algorithm
      $cipher_alg = MCRYPT_TRIPLEDES;
      $iv_size = mcrypt_get_iv_size($cipher_alg , MCRYPT_MODE_ECB);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
      $encrypted_string = mcrypt_encrypt($cipher_alg, $key, $password, MCRYPT_MODE_ECB,$iv);
      return $encrypted_string;
}
Fixer of Problems
CERTIFIED EXPERT
Most Valuable Expert 2014
Commented:
That's it.  Here's the PHP page: http://us3.php.net/manual/en/function.mcrypt-encrypt.php

Here is some info for someone who is in the same situation as you: http://stackoverflow.com/questions/5749859/triple-des-decryption-in-classic-asp

Author

Commented:
Thanks to all.

Jeez... what great value EE.