I've protected delete queries on my forms with a password (did it with some VBA) and I let the user change the password so I can't just compare it to a text when I ask the user to enter the password, is there any way I could save the password variable on access storage without a table?
currently, I'm saving the password on a table with one field and doing the comparisons at the background...
It's a school project.
I would suggest hashing the password and storing the hash in your table; then, when the user enters a password, hash the entered password and compare the result with the stored hash.
This approach has the benefit that no passwords are stored in human readable format, and the hashing process cannot be reversed to yield the plain text password from the stored hash (one could only brute-force guess the password and compare the resulting hash).
You can save the password, but better password hash as advised #Lee Mac in the database properties. Property can be changed at any time by code. Change remains in the database file after database closing.
Create property:
Function CreatePropery()
Dim DB As Database
Dim P As Property
Set DB = CurrentDb
Set P = DB.CreateProperty("MyPassword", DB_TEXT, "MyInitialPassword")
DB.Properties.Append P
End Function
Get current password:
Function GetPasswod()
GetPasswod = CurrentDb.Properties![MyPassword]
End Function
Set new password:
Function SetPassword(strNewPassword As String)
CurrentDb.Properties![MyPassword] = strNewPassword
End Function
Related
I have a collection of accounts with passwords encrypted with bCrypt in my Fauna database. How do I find the correct account when given the password in plain text?
When I was not encrypting the password, this is the query I was using:
const password = 'abc123'
faunaClient.query(
q.Count(
q.Match(q.Index('getAccountByPassword'), password))
)
But this obviously isn't going to work anymore.
So what I need to do is getting all the hashed passwords in my database and then compare them to my plain text password. I don't have a name, email or something similar, to initially identify the account and then compare the passwords. I only have the password.
Create an index that specifies the field holding the hashes as a term, then you can search for the hash. You'll need to bCrypt any provided password first.
Alternately, you could use Fauna's built-in authentication. When you create a document representing an identity (e.g. a user), you can set a credentials field:
Create(
Collection("users"),
{
data: {
username: "alice",
...
},
credentials: { password: "abc123" },
}
)
The credentials field is never stored: it is used to create a Credentials document. Then, you can use Login(<reference to identity document>, <password>) to acquire a token. The token's secret can then be used as a password-equivalent when executing Fauna queries, and ABAC roles can specify what privileges that the token's identity can perform.
For more details, see:
Login function
Logout function
User Authentication tutorial
I use crypt() to encrypt passwords for a project of mine. When the password is chosen by the user, it's encrypted like this:
password = crypt(<password chosen>, <user's account name>)
The problem is when the user logs in using their password. If what they type doesn't match their password, it should enter this if check:
if (strcmp(crypt(<what user types in as password>, <user's account name>), <user's encrypted password>)) {
//...
}
It doesn't in one certain scenario. Let's say their password is 'asdf'. If they enter 'asdf' with any random trailing characters, such as 'asdffffff' or 'asdf339sfd', it still accepts the password. It seems to ignore everything after 'asdf'.
Is this a known issue with crypt? Is there another way to encrypt passwords?
The second argument to crypt is not supposed to be the user's account name. It's supposed to be a setting string. Setting strings look like this:
$2b$07$fQuDK3TaQP4sw6IX6iVcTw
The $2b$07$ part tells crypt which password-hashing algorithm to use, and the string of random characters that follows is the salt. The salt must be different for each user, but it is not supposed to have any correlation with the user's account name. It doesn't technically have to be random, but it's critical that it be different for each user, and it needs to change every time the user changes their password, so best practice is to use a long string drawn from a cryptographic PRNG.
When you authenticate a user who has logged in before, you use the stored hashed password as the setting string:
char *new_hash = crypt("password typed in", "stored hash");
if (new_hash && !strcmp(new_hash, "stored hash")) {
// user has successfully logged in
}
This works because the stored hashed password always begins with the setting string that was used to create it in the first place, and crypt is coded to look only at the setting-string part.
(Also note the null check; some implementations of crypt can fail and report failure by returning a null pointer.)
When you create a new account or change a password, you have to generate a new setting string. If you have the function crypt_gensalt, use that:
char *new_setting = crypt_gensalt("$2b$", 0, 0, 0);
if (new_setting) {
char *new_hash = crypt("user's new password", new_setting);
// ...
} else {
// halt and catch fire
}
If you don't have crypt_gensalt you have to implement it yourself, unfortunately. (To make matters worse, some Unixes have the crypt_gensalt whose documentation I linked to above, and others have a different version, with the same name, doing the same job, but taking different arguments. Time to dust off your Autoconf skillz!)
Now you know all of that, I can explain why
password = crypt("password chosen", "user's account name");
appeared to work but truncated the password. Your user account names probably begin with at least two alphanumeric characters, right? Like, "Ma[ya]", or "zw[ol]"? Unfortunately, any two alphanumeric characters make a valid setting string ... that selects one of the oldest and least secure password-hashing algorithms known to science, descrypt. (It was pretty good when it was invented ... in the mid-1970s. Nowadays, it can be cracked by brute force no matter what the password is.) One of the many problems with this algorithm is that it truncates all passwords to eight characters. asdf and asdfhjkl hash to different things, but asdfhjkl and asdfhjkl1234 hash to the same thing.
The cure for this is to use crypt_gensalt or equivalent to select a modern algorithm. All the modern algorithms accept arbitrarily long passphrases.
starting with programming and would like tips on writing pseudocode for a 2 Dimension array in a main class that stores usernames and passwords for each account.
Program should take a username input, store it in the array - preferbly using a function(Function that adds usernames and passwords or different functions adding each seperately), and then a password store it in a correspoding dimension to the user name enter - for an array sizeof 10: ArraySize(10)(10) all
Should be able to login(Account Search Function - could search both password and function using the same function or two function searching each part separetly) to the account with check of password combination(Function that checks password limit = 3)
Should be able to delete. So login first, and then delete an invidual account.
I am currently attempting to design a database that requires a number of users inputting data via forms.
one of these tables is a 'user' table. Amongst the information in the table is
userid (int),
username (text),
first name (text),
last name (text)
In the even that I'm filling out a form and supply the the username in the username field is it possible if the username already exists to pull the first name and last name from the user table and auto-populate those form fields? If so can you point me in the right direction please?
Directly via access functionality or via vba? If not possible in 2003 is this possible in 2007?
Ok now for the auto fill (yes i did find one example), This will fill the username after you filled the userid (Both should be comboboxes in this case called Usernamecombo and useridcombo)
First make the query with a SQL similar to this:
SELECT [User].username FROM User WHERE ((([User].userid) Like '*' & [Forms]![Yourform]![useridcombo] & '*'));
Lets call this query "qry_username".
Then go to designview of the form and to the properties of the useridcombo, in the event/afterupdate property you make a event procedure (VBA) :
Private Sub useridcombo_AfterUpdate()
[Forms]![yourform]![Usernamecombo].Value = DFirst("username", "qry_username")
Forms("yourform").[Usernamecombo].Requery 'this last line is optional
End sub
Other fields can be added to the VBA pretty simply(dont forget the query)
Private Sub useridcombo_AfterUpdate()
[Forms]![yourform]![Usernamecombo].Value = DFirst("username", "qry_username")
[Forms]![yourform]![Firstnamecombo].Value = DFirst("Firstname", "qry_username")
[Forms]![yourform]![Lastnamecombo].Value = DFirst("Lastname", "qry_username")
Forms("yourform").[Usernamecombo].Requery 'this last line is optional
End sub
I have a similar form and i use to make these field as Comboboxes.
Then set the property row source as a query.
Set the criteria Where like this
WHERE ((([Users].Username) Like '*' & [Forms]![YourForm]![Username] & '*'));
This will allow the user to choose the name as fast as possible
But it will not fill it automatically because my users can have the same username as others.
I'm writing a program and before it loads I want the user to enter the correct password without storing the password anywhere in my code. I've implemented MD5 hashes before but from what I've read they're outdated and can be broken. There are a few sites out there that attempt to reverse engineer and MD5 hash. What's the strongest encryption I can use to keep prying eyes out of my program (e.g., The NSA)?
"Encryption" is not the right thing to do for storing user passwords - as by design an encrypted password can be decrypted. As you said - hashing is the way to go.
MD5 is outdated, and I believe the current recommendation is sha1.
Note that there are ways to reverse any hashing algorithm to acceptable input. The commonly accepted standard to make this much more dificult is to add a unique "salt" to all passwords before putting them through the hashing function. A common mistake made when adding salts to passwords is to use the same salt value on every password in the database.
When salting passwords, use a unique value, for example the user ID, or the created date/time string for the user record. This will prevent attacks based on rainbow tables because there will be no existing ready to use rainbow table for your stored password hashes.
I personally like the approach of using the created date / time string of the user as it's a value that should never change and will be available and will likely be different for each user the the database.
Eexamples below assume you are familiar with PHP - however the concepts can be applied to any language.
Example:
Before saving a new user into the database:
$date = date('Y-m-d H:i:s');
// save this same value into the user record somewhere
$passwordHash = sha1($user['created_date'].$_POST['password']);
// and save the $passwordHash value into the password field for that user
To authenticate a login attempt, use something like the following:
function authenticateUserLogin($email, $password) {
$user = $db->fetchRow('SELECT * FROM users WHERE email=?', array($email));
if (!$user) return false;
$passwordHash = sha1($user['created_date'].$password);
return $user['password_hash'] !== $passwordHash;
}
To update an existing users password, use something like...
$passwordHash = sha1($user['date_created'].$newPassword);
$db->query('UPDATE users set password_hash=? WHERE id = ?', array($passwordHash, $user['id']));