Authenticate with ASP.NET membership provider using Qt and C++

5. July 2012 00:42 by Cameron in   //  Tags: , , , , , ,   //   Comments

Today, I was looking at a method of authenticating users in the IGA desktop application using the website's membership provider. I remembered a post I made a while back on Stack Overflow about how to authenticate users with Ignite OpenFire and in the answer, there was some Java code showing how to correctly hash a password with a salt and compare it with the membership table. I ventured into porting the algorithm to C++ and was successful! Here's the C++ code for anyone interested:

QString hashPassword(QString password, QString salt)
{

    // get utf-16 representation of password

    QByteArray passwordBytes((const char*) (password.utf16()), password.size() * 2);

    // get utf-16 representation of salt

    QByteArray saltBytes((const char*) (salt.utf16()), salt.size() * 2);

    // decode base64 salt byte array

    QByteArray saltDecodedBytes = QByteArray::fromBase64(saltBytes);

    QByteArray dst;

    dst.append(saltDecodedBytes);

    dst.append(passwordBytes);



    QByteArray hashed = QCryptographicHash::hash(dst, QCryptographicHash::Sha1);

    return QString::fromLatin1(hashed.toBase64().data());
}

Please note that in order for this to work, your passwords must be hashed. I had to convert any non-hashed passwords using an automated script that I found on Stack Overflow. It's pretty straight forward. Just add a second provider that uses hashed passwords and get the passwords from the encrypted/clear text provider and change them using the hashed provider. Be sure to set your default provider to the hashed provider so that you won't have to run this script at a later point. I had to modify the code that I found from Stack Overflow a bit to use a try catch block around the user.GetPassword() method as some passwords may already have been hashed and can't be decrypted. Here's the C# code for anyone interested:

void HashAllPasswords()
{          
	SqlMembershipProvider hashedProvider = (SqlMembershipProvider)Membership.Providers["HashedProvider"];
	SqlMembershipProvider encryptedProvider = (SqlMembershipProvider)Membership.Providers["EncryptedProvider"];
	if (encryptedProvider == null || hashedProvider == null) return;
	Dictionary<string, string> passwords = new Dictionary<string, string>();
	int unimportant;
	foreach (MembershipUser user in encryptedProvider.GetAllUsers(0, Int32.MaxValue, out unimportant))
	{
		try
		{
			passwords.Add(user.UserName, user.GetPassword());
		}
		catch (Exception e)
		{
		}
	}

	using (var conn = new SqlConnection(
		   ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString))
	{
		conn.Open();
		using (var cmd = new SqlCommand(
			   "UPDATE [aspnet_Membership] SET [PasswordFormat]=1", conn))
			cmd.ExecuteNonQuery();
	}

	foreach (var entry in passwords)
	{
		var resetPassword = hashedProvider.ResetPassword(entry.Key, null);
		hashedProvider.ChangePassword(entry.Key, resetPassword, entry.Value);
	}
}

Month List

Tag cloud