So I'm developing a website using php, mysql and javascript, and also 'sha512' to encrypt passwords of members using the code :
$password = filter_input(INPUT_POST, 'p', FILTER_SANITIZE_STRING);
$random_salt = hash('sha512', uniqid(mt_rand(1, mt_getrandmax()), true));
$password = hash('sha512', $password . $random_salt);
the p value is comming from :
function formhash(form) {
var password = randomString();
var p = document.createElement("input");
form.appendChild(p);
p.name = "p";
p.type = "hidden";
p.value = hex_sha512(password.value);
password.value = "";
form.submit();
}
function randomString() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for( var i=0; i < 9; i++ )
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
My idea here is to reset user password by entering their email and generate random 8 characters then send it directly to their email.
The problem I'm facing now is how to get the actual password (not encrypted) that has been generated so it can be automatically sent to the email of the member who requested to reset their password?
Good question.
First, you should never send users their passwords in plaintext. It's considered a bad security practice for a few reasons. If anyone gets access to the email, then they have the password and can hijack the user account. Second, hashing is a one-way form of encryption where you turn the password into gibberish. The big value in hashing is that the same password will always be turned into the same gibberish-- everytime. This means you can do password matching without ever storing the raw password. The reason you're supposed to hash a password and not do 2-way encryption like AES-256, is that 2-way encryption requires the creation, management, and securing of encryption keys which can be hard. Hashing is just easier and more secure for the vast majority of developers.
So how should you implement password reset if you can't send the raw password?
You send the user an email with a link to a secure reset page AND a one-time use reset token that expires within a certain window. This way, if someone get's access to the email then the window of risk is limited to the short window.
There are a variety of ways to build this yourself but an easy approach to getting a one-time use token you don't have to store or manage is to offload user management to a microservice like Stormpath where it takes care of all the user management for you-- password reset, password storage, user profiles, authentication, etc.
For password reset here's what it would look like:
User initiates password reset work on a web page
You make API call to stormpath with user's email address or username
Stormpath sends out reset email to user (your "from" address, custom HTML, etc) with a link + token. The reset token that is unique, one-time use, and expires if not used within 24 hours
User clicks on the link and lands on the reset page
You pull the token from the URL and check Stormpath for token verification
User submits new password
Stormpath sends out reset success message (your "from" address, custom HTML, etc)
You can build your own UIs in this flow so the user never knows Stormpath exists.
Now, you don't have to manage, store, or secure any passwords or reset tokens in your database.
Here's are some links to the community-managed PHP SDK.
http://docs.stormpath.com/php/quickstart/
http://docs.stormpath.com/php/product-guide/
Full Disclosure - I work at Stormpath
and also 'sha512' to encrypt passwords
You're not encrypting them, you're hashing them. A hash is a one-way function. You can't take the result of a hash function and get the original. There are many possible original chunks of data that can result in the same hash.
The whole point of hashing in this context is to be able to check passwords without ever actually storing the user's password. You shouldn't send the user their password in e-mail, as e-mail is sent over the internet unencrypted. If you must have the original pre-hashed data for some reason, you must store it before you hash it.
Related
On the site, the login is made using a code of the type if the entered password matches the variable in which the password is stored, then the person enters the site. How to protect the site from the magic F12 button? I.e. how to make the password impossible to find
out
p.s. I have never done anything like this so the experience is 0.
I wrote the code and don't know how to protect passwords.
function checkUsernamePassword() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
if (username == "admin" && password == "12345") {
window.location = "../index.html";
}
else {
window.location = "invalid-login.html";
}
}
Ordinarily, your approach would be easily bypassed.
However, with the WebCrypto API you can use strong encryption to protect the data that needs to be accessed with a password.
You'd use a salted PBKDF2 to stretch the password into a symmetric encryption key. Then, the data can only be accessed when the correct password is entered.
This approach relies on the password being of sufficient entropy to prevent a brute-force attack.
When users register, some emails get into the spam folder.
I have two functions:
The first will make a configuration for nodemailer.
function sendingLetter() {
return nodemailer.createTransport({
service: config.transport.service,
secure: config.transport.ssl,
auth: {
user: config.transport.user,
pass: config.transport.password
}
});
}
The second is making a template for sending by mail with a link
function statusCheck(file, replacements) {
let html_file = fs.readFileSync(file, { encoding: 'utf-8' });
let template = handlebars.compile(html_file);
let htmlToSend = template(replacements);
return htmlToSend;
}
The function of sending letters to the user's mail
const smtpTransport = sendingLetter();
const confirm_email = path.join(__dirname, '../views/email_templates/users/confirm_email.html');
...
let rand_hash = Date.now();
let link = 'https://' + config.kHostName + '/api/users/verify/' + rand_hash;
let replacements = {
target_link: link,
};
let htmlToSend = statusCheck(confirm_email, replacements);
let mailOptions = {
from: config.transport.user,
to: user_email,
subject: Constants.users.messages.subjectConfimEmail,
html: htmlToSend,
};
smtpTransport.sendMail(mailOptions);
The template in which the link will be inserted to be sent to the user by mail
<p>
We're ready to activate your account. All we need to do is make sure this is your email address.
</p>
<a href="{{target_link}}"
<div class="butten">
Confirm Email
</div>
</a>
In some cases, Google sends my email to a spam folder. Why it happens? What are some tips to avoid this?
There is an algorithm within Google to categorize the messages according to your interest and have probably been categorized as undesirable.
The classification of messages sent from any website as spam is one of the most important things that a webmaster should pay attention to. I will discuss in this article what things a webmaster should pay attention to to ensure that messages sent by him Its website as spam (spam) ends up in a non-spam folder or spam folder.
How do service providers classify messages as spam?
The e-mail service providers use many methods and tools to filter the incoming e-mails of the system and accordingly decide whether or not the message should be classified as an annoying message.
Content-based filtering "Content Filters"
Filter based on the letterhead of the email "Email Header Filters"
Filter based on blacklists "Blacklist Filters"
Filter based on user decision "User Rule-based filters"
Methods of Solution
First: Filter based on Content Content Filters
Through which the content of the message and the method of writing it to find out whether the message is disturbing or not, by comparing the content to a database containing a set of words used in the spam and certainly every service provider has his own words in this area called " Spam Trigger Words, "and there are many lists of English words that can be found using the previous search term in the Google search engine.
Also, the service providers, through this mechanism, search the way in which the message was written, especially if the HTML code was used to write the message, then the service provider makes sure that the code written is a clean code.
The following are some tips that can be provided to avoid placing your message as spam based on the filtering mechanism based on the content:
Make sure that the title of the subject is not too long and not so short that it is just one word.
Make sure that the title or text of the message is not fully capitalized when writing in English.
Make sure that the message title does not contain Re: unless the message is actually in response to a message sent by the recipient.
Do not use a question mark in the message title.
You can use the $ $ sign in a sequential address or message content, for example, $$$.
When you write a message in HTML, do not use video, JavaScript or JavaScript in the message, and make sure that the HTML code is clean, standard and written correctly according to HTML standards.
Second: Liquidation Based on the letterhead "Email Header Filters":
Through this mechanism the server receives the message of the search for any false data can be found in the letterhead and accordingly classified as an annoying message or not.
Third: Liquidation based on blacklists "Blacklist Filters":
Blacklists are constantly updated databases that contain a list of IP addresses for servers that are based on or send spam messages.
Fourth: Liquidation based on the user's decision "User Rule-based filters":
Although this mechanism is not of great importance because it depends on the decision of the recipient of the message itself, but it must be mentioned, and in this mechanism the recipient of the message itself to indicate the message received as an annoying message and therefore in the following times to be written by the same address The message will go to the spam folder directly.
In the end I apologize for my relatively weak English.
Hello I need some help with this issue after I search the solution and I have not found yet,
I want to compare 2 hash password with bcrypt of the same password,
how do I do it?
for example:
I have these 2 hash password that came from the same password in bcrypt:
var password = E#Js#07Do=U$
var hash1 = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
var hash2 = $2a$10$mgApOcRIp7RSK3lRIIlQ5e/GjVFbxAFytGAEc0Bo17..r8v2pPR22
// that's not working for me
bcrypt.compare(passwordHash, userPasswordLoginHash, function(err, isMatch) {
if (err) throw err;
if(isMatch){
console.log('correct password!')
}
callback(null, isMatch);
});
how can i compare them, to determine that they came from the same password, by using bcryptjs npm package?
This is impossible by design - as a core security property of true password hashing.
If you could compare two password hashes without knowing the original password, then if an attacker cracked one password on the system, they would instantly know the passwords of all users who are using that password, without any additional work. It should be immediately obvious why this would be a bad thing.
For example, if passwords were stored using a hash inappropriate for password storage (such as MD5), then if 50 users had a password of 'password', then all of their hashed passwords would have the identical MD5 hash ('5f4dcc3b5aa765d61d8327deb882cf99'), and cracking one of them would reveal the password of all 50 users.
You can't do that with a modern password hash like bcrypt. The only way to "compare" two modern password hashes is to know the plaintext in advance, and then apply the algorithm using the salt in each hash. And even if two users have the same password, the attacker has to perform the same expensive computation to crack each of them independently, because the unique salts make each hash unique.
More generally - and this may sound a bit bold - but there is no legitimate use case for any system or administrator to ever compare two different users' passwords. User passwords should be 100% independent and 100% opaque to the system once stored. If a system or business case requires this kind of comparison, it should be redesigned to eliminate that requirement.
"With bcrypt lib you compare plain text password to the one hashed using the same lib."
The problem is with a micro services architecture, that is very insecure. If I have a front end passing an unhashed password to the backend, the unhashed password is getting logged (possibly in multiple places) before it gets compared against the hash in the DB on the system backend.
With bcrypt lib you compare plain text password to the one hashed using the same lib.
Say you hashed a password
const myPlaintextPassword = 'E#Js#07Do=U$'
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
// Store hash in your password DB.
// example output, taking your hash
// hash = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
});
You compare like:
// db query, get hashed password, found hash
// hash = $2a$10$fKAyjaG0pCkisZfRpKsBxursD6QigXQpm1TaPBDZ4KhIZRguYPKHe
// User input again:
const myPlaintextPassword = 'E#Js#07Do=U$'
bcrypt.compare(myPlaintextPassword, hash, function(err, res) {
// res is true as the original password is the same
// res == true
});
For a bit extra security you can encrypt the password in the front-end and decrypt and compare in the back-end
I can't figure out how to get the enrollment token from the Accounts.sendEnrollmentEmail function.
I know this function sends a direct mail towards the user which in the end looks something like this:
http://localhost:3000/#/enroll-account/FCXzBbqHInZgBlLaOpu8Iv11jP9DJEG-e1auAHDsh6S
However, I would need to somehow get only to the token part FCXzBbqHInZgBlLaOpu8Iv11jP9DJEG-e1auAHDsh6S as I want to send enrollment mail trough a different service (e.g Postmark)
How to do this?
The Accounts.sendEnrollmentEmail(userId, email) function generates a random token and saves it in the user's services.password.reset.token field.
The code that generates the token is:
var token = Random.secret();
var when = new Date();
var tokenRecord = {
token: token,
email: email,
when: when
};
Meteor.users.update(userId, {$set: {
"services.password.reset": tokenRecord
}});
(You can view the function's source code here).
It then sends an email to the user using the Email package. If you want to use a different service to send the email, you basically have 2 options:
Use the same convention yourself (i.e, create the same record and use your own email service in your own function).
Use the existing function, allow the mail delivery to fail silently and then query the user's document for the token and send the email yourself.
Neither is a particularly good option, but both will work for the time being. I wish they had refactored this part into its own function.
Note that the accounts packages are expected to undergo some changes towards the release of the next Meteor versions.
BTW, this function is very similar to Accounts.sendResetPasswordEmail, which you may also wish to override or create your own version.
I use the nodejs bcrypt library for better password protection.
I am not sure i understand exactly how to use it, but i got this so far:
//A module containing this login function:
login: function(credentials,req,res) {
//"credentials" is containing email and password from login form
var query = 'SELECT password, email FROM users WHERE email = ? LIMIT 1';
client.query(query,[credentials.email], function(err, results) {
if (results[0]) {
//Compare passwords
if (bcrypt.compareSync(credentials.password, results[0].password)) {
//Set session data and redirect to restricted area
}
}
});
}
I removed all the error handling here in the example so that its easier to read the code.
1.This works and i am able to login and set the session. But is this all there is to it? Am i missing something?
2.Looks like the salt is prepended to the password when generating hash. Dont I have to save the salt in db?
Any help appreciated
Yes, this is all there is to it! The salt you generate when encrypting the password originally is used to prevent against rainbow table attacks; you do not need to persist it.