More secure passwords

Storing a plain-text password in a DB leaves your system open to abuse from anybody with access to the tables (sys admin for example). Here is the technique I recently used. Instead of storing the password itself I store a hash of the password, and a random "salt" that was used to create the hash to make it less predictable.

[UmlTaggedValue("Eco.Length", "255")]
private string PasswordHash

[UmlTaggedValue("Eco.AllowNULL", "True")]
[UmlTaggedValue("Eco.Length", "40")]
private string PasswordSalt

As you can see I do not store the password, just a hash + salt, both of
which are private. Here are the methods used to set the values of these properties.

public void SetPassword(string newPassword)
if (newPassword == null)
throw new ArgumentNullException("password");
if (newPassword.Length < 6)
throw new ArgumentException("Password must be at least 6 characters");

PasswordSalt = Guid.NewGuid().ToString();
PasswordHash = EncryptPassword(newPassword);

private string EncryptPassword(string password)
TripleDESCryptoServiceProvider des;
MD5CryptoServiceProvider hashmd5;
byte[] pwdhash, buff;
hashmd5 = new MD5CryptoServiceProvider();
pwdhash = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(PasswordSalt));
hashmd5 = null;
des = new TripleDESCryptoServiceProvider();
des.Key = pwdhash;
des.Mode = CipherMode.ECB; //CBC, CFB
buff = ASCIIEncoding.ASCII.GetBytes(password);
string result =
buff, 0, buff.Length)
return result;

Now the code required to get a user by ID/Password

public static User FindUserByUserIDAndPassword(IEcoServiceProvider serviceProvider, 
string userID, string password)
string query =

User user =
BusinessClassesHelper.SelectFirstObject(serviceProvider, "User", query);

if (user != null && user.EncryptPassword(password) == user.PasswordHash)
return user;
return null;

The BusinessClassesHelper is a class with static methods to help with OCL operations, such as escaping user input values to avoid OCL injection.

using System;
using System.Collections.Generic;
using System.Text;
using Eco.ObjectRepresentation;
using Eco.Services;
using Eco.Handles;

namespace xxxxxxxxxxxxxxx
public static class BusinessClassesHelper
public static string EscapeOcl(string ocl)
if (string.IsNullOrEmpty(ocl))
throw new ArgumentNullException("ocl");

ocl = ocl.Replace("\\", "\\\\");
ocl = ocl.Replace("'", "\\'");
return ocl;

public static T SelectFirstObject(IEcoServiceProvider serviceProvider,
string className, string criteria)
if (serviceProvider == null)
throw new ArgumentNullException("serviceProvider");
if (string.IsNullOrEmpty(className))
throw new ArgumentNullException("className");
if (criteria == null)
throw new ArgumentNullException("criteria");

IOclPsService psService =
IOclService oclService =

IObjectList result =
psService.Execute(className + ".allInstances" + criteria);
result =
oclService.Evaluate(className + ".allLoadedObjects" + criteria) as IObjectList;
if (result.Count == 0)
return default(T);
return (T)result[0].AsObject;

No comments: