Jump to content
SaranacLake

Safely Hashing Data

Recommended Posts

16 hours ago, SaranacLake said:

What is the latest and greatest way to hash data in PHP?

Password or text? 

Share this post


Link to post
Share on other sites

As others have alluded to it all depends on the content source to be hashed and, most importantly, the purpose for the hash. For example, some people may say to never use MD5 because it has been compromised. While it should not be used for passwords, it is perfectly acceptable and even preferred for some purposes. So, there is no way to appropriately answer your question as it is too general. Sort of like answering what is the best automobile.

Share this post


Link to post
Share on other sites

Sorry, I didn't see your replies.

I was asking about passwords.  (What other places would you use hashing?)

Currently in my code - which has sat on the shelf for a couple years - I am using...

	$loginHash = hash_hmac('sha512', $pass . $salt, VINEGAR);
	

Thoughts?

 

Share this post


Link to post
Share on other sites

Unless you're 110% sure that you know what you're doing, like really know and didn't just copy some code you found on the internet, then you should be using password_hash().

Share this post


Link to post
Share on other sites
15 hours ago, requinix said:

Unless you're 110% sure that you know what you're doing, like really know and didn't just copy some code you found on the internet, then you should be using password_hash().

The line of code I posted above seems pretty idiot-proof, so based on your response, apparently that is an outdated approach and password_hash() is superior, huh?

 

 

Share this post


Link to post
Share on other sites
1 hour ago, SaranacLake said:

The line of code I posted above seems pretty idiot-proof,

I'm not asking if you think the code looks solid. Do you understand HMAC? SHA512? Salting? Fully? Like are you willing to apply for some sort of certification regarding cryptographic knowledge?

I don't think so. So use password_hash.

Share this post


Link to post
Share on other sites
39 minutes ago, requinix said:

I'm not asking if you think the code looks solid. Do you understand HMAC? SHA512? Salting? Fully? Like are you willing to apply for some sort of certification regarding cryptographic knowledge?

I don't think so. So use password_hash.

It sounds like password_hash uses bcrypt by default.

Would you agree that bcrypt is probably one of the strongest ways to hash something in 2019?  Or is there something even better?

 

 

Share this post


Link to post
Share on other sites
18 hours ago, requinix said:

Do you understand HMAC? SHA512? Salting? Fully? Like are you willing to apply for some sort of certification regarding cryptographic knowledge?

 

17 hours ago, SaranacLake said:

Would you agree that bcrypt is probably one of the strongest ways to hash something in 2019?

I don't think requinix could have put it any better.  Unless you're doing a master thesis on this stuff, there's really no point in asking such questions.  There isn't so much one that is "better" than the other, they're just tools.  It's up to the developer/engineer to use them as they see fit.  MD5 has its bad rap, but perhaps someone needs it for whatever reason. 

If I asked you what the best hammer to use for 2019, then you would get a myriad of answers and opinions.

 

 

Share this post


Link to post
Share on other sites
21 hours ago, SaranacLake said:

It sounds like password_hash uses bcrypt by default.

It does for now. The documentation also mentions that the default "is designed to change over time as new and stronger algorithms are added to PHP."

For what it's worth, the PHP manual has an FAQ-like page for hashing passwords here:
https://www.php.net/manual/en/faq.passwords.php

Share this post


Link to post
Share on other sites
Posted (edited)
3 hours ago, Zane said:

 

I don't think requinix could have put it any better.  Unless you're doing a master thesis on this stuff, there's really no point in asking such questions.  There isn't so much one that is "better" than the other, they're just tools.  It's up to the developer/engineer to use them as they see fit.  MD5 has its bad rap, but perhaps someone needs it for whatever reason. 

If I asked you what the best hammer to use for 2019, then you would get a myriad of answers and opinions.

 

 

Masters thesis, no.  But am I trying to learn more each day to be a better developer and produce more *secure* solutions, YES!!

The advice above is like saying, "Unless you are ASE certified, then you should NOT change your own oil or learn to do basic auto maintenance..."

Ridiculous, really.

 

**Edited to add the word "NOT" above!!  🙂

 

 

Edited by SaranacLake

Share this post


Link to post
Share on other sites

So you are basically saying that the people who HAVE learned stuff and HAVE written the php functions to perform hashing for us users already have NOT done a good enough job for you?

Interesting....

Share this post


Link to post
Share on other sites
Posted (edited)
8 minutes ago, SaranacLake said:

The advice above is like saying, "Unless you are ASE certified, then you should change your own oil or learn to do basic auto maintenance..."

Kinda, yeah. But changing your oil and cryptography are very different things. Your users are trusting you with sensitive information like their email address and password.

If I needed my car to bring me cross-country and I had to bring my spouse and children with me, I wouldn't change my own oil. It's fine that I know how to do it, and for simple situations I would, but when it really matters I will set aside my own desires and trust the people who really know what they're doing.

[edit] Cryptography is the same in that respect, but it has a much higher bar to meet in order to be even somewhat good at it. "Rolling your own" version could go well and you could get it right, or you could do it poorly and compromise the integrity of the hash. What basic programmer education will teach you about passwords is enough so that you don't do it so terribly that the false sense of security of having "hashing" obscures the actual insecurity of what was designed.

Edited by requinix
added a little bit more

Share this post


Link to post
Share on other sites

Now that I know that the PHP function, password_hash(), and the hashing algorithm, "bcyrpt" are recommended for best hashing security when using PHP, I have a follow up question...

Would it be secure to hash something like "credit_card_used" and "last-4 of credit card" and store those as hashes either outside of webroot on my VPS, or maybe in MySQL?

In my OP, and subsequent posts, I am trying to get a better grasp of how "secure" hashing is...

a.) Because if my website ever got hacked, I want the peace-of-mind that at least my users hashed passwords are safe - or at least safe long enough for people to reset things

b.) Because i would like to do the following, IF, it can be done "securely"...

Capture and store as a hash the credit card type and last-4 of the credit card when a customer subscribes on my website, so that I have a way to limit the number of accounts on a given credit card to "2".

From what I have read in the past - and this could be outdated - it would take decades to try and crack a piece of data hashed using SHA-512.

IF that were true, then at least technically, you could reasonably hash something like last-4 of a cc and be safe.  (Whether this is legal is another issue I'd have to research?!)

 

 

Share this post


Link to post
Share on other sites
7 minutes ago, ginerjm said:

So you are basically saying that the people who HAVE learned stuff and HAVE written the php functions to perform hashing for us users already have NOT done a good enough job for you?

Interesting....

Your logic is way off today.

No, I have NOT critiqued anything regarding how PHP hashes data.

I DID say that I would like to better understand how things work and what options are out there so I can make more informed decisions.

To say, "Just use password_hash, and don't try to learn anything about it" is a great formula for getting into a security issue down the road.

I no longer work on my own car, but I pretty much understand how everything in it works.  And so when I make choices on maintaining or repairing my car, I can make wiser decisions.

 

Share this post


Link to post
Share on other sites
Posted (edited)
7 minutes ago, SaranacLake said:

Would it be secure to hash something like "credit_card_used" and "last-4 of credit card" and store those as hashes either outside of webroot on my VPS, or maybe in MySQL?

Credit card data is a whole 'nother ball of wax. If you're storing it in any form and you don't already know about PCI compliance then stop storing it and learn about that.

Quote

a.) Because if my website ever got hacked, I want the peace-of-mind that at least my users hashed passwords are safe - or at least safe long enough for people to reset things

If you do the hash right. And since that's a hard target to hit, use password_hash().

Quote

From what I have read in the past - and this could be outdated - it would take decades to try and crack a piece of data hashed using SHA-512.

Not when you know that the input is 15-16 characters long and consists only of digits.

[edit] And one of those digits is a checksum so the real input is actually 14-15 digits.

[edit 2] And credit card numbers all start with one of a fixed set of prefix digits...

Edited by requinix

Share this post


Link to post
Share on other sites
7 minutes ago, requinix said:

Kinda, yeah. But changing your oil and cryptography are very different things. Your users are trusting you with sensitive information like their email address and password.

If I needed my car to bring me cross-country and I had to bring my spouse and children with me, I wouldn't change my own oil. It's fine that I know how to do it, and for simple situations I would, but when it matters I set aside my own desires and trust the people who really know what they're doing.

At no point did I say that I intended on rewriting password_hash(0 or bcrypt?!

I'm just asking questions like "Is there something more secure?" and "Do I need to do anything else to make it secure" and so on.

Share this post


Link to post
Share on other sites
Just now, SaranacLake said:

At no point did I say that I intended on rewriting password_hash(0 or bcrypt?!

Your second post in this thread was "here's some code that does a hash and it looks fine to me".

Just now, SaranacLake said:

I'm just asking questions like "Is there something more secure?" and "Do I need to do anything else to make it secure" and so on.

Sure, you can be more secure: use even stronger hashes, even higher computation costs, even longer salts... But where do you stop?

Share this post


Link to post
Share on other sites
3 minutes ago, requinix said:

Credit card data is a whole 'nother ball of wax. If you're storing it in any form and you don't already know about PCI compliance then stop storing it and learn about that.

If you do the hash right. And since that's a hard target to hit, use password_hash().

Not when you know that the input is 15-16 characters long and consists only of digits.

[edit] And one of those digits is a checksum so the real input is actually 14-15 digits.

I am familiar with what PCI compliance is - can't say I know what it says in 2019.

And since PCI is a "policy" document that does NOT - at least when I studied it years ago - dictate "implementation", I figured it safer to ask coding experts about how to securely store things like passwords and maybe more.

So back to my earlier question...

1.) Is I use PHP's password_hash() is that suffciently secure that if my website ever got hacked, that I would have time to notify users to reset their passwords and basically everyone would be safe?

1b.) OR, is password_hash() and bycrypt NOT secure enough to offer that level of protection?

2.) If the answer to 1b.) is "Not secure enough to offer that level of protection", then what is?

3.) Is there any practical way to store something like the last-4 of a credit card in a hash and have it NOT be hackable except maybe by some nation-state?  Or put more simply, how do companies store things like customer names and billing details so they can manage customers and provide further services, AND how do companies retain full credit card details for things like recurring billing? 

Yes, these may be steep "asks", but hey, i want to learn how larger companies do this, because it is important to growing a business.  (And there must be a secure way to do such things online, because lots of companies already do!)

Again, just trying to expand my knowledge...  🙂

 

Share this post


Link to post
Share on other sites

There's no black and white way of answering this.  You pick your method for security (hashing, encrypting, obfuscating, etc, all of the above) and basically cross your fingers; keep an eye out in your logs for intrusions/breaches.  It's a full time job in itself.  Lately, large corporations have been breached and they most likely have a team to handle security, yet the corporations were breached anyway.  Experian, Capital One, Adobe, Equifax, and on and on.  These are corporations that maintain tens of millions of very very sensitive PII.  There will always be someone (even multiple people) out there that can breach a security setup if they so please.  So, to ask what the  "best" method is, is just.. so gray of an area to get into that I can't really explain it.

Also, for the record, you should just not store credit card information, like ever.  That's a big liability to take on, a lot of responsibility.  There are online merchant providers that can handle that kind of stuff, like Authorize.net.  Let someone else host that stuff.  If I were in your shoes, I wouldn't be dabbling and experimenting with security on a production level for things like credit cards, SSNs, etc...  If you're wanting to get a firm grasp on the intrinsic minuscule details and drawbacks, create a "secure" environment, and try to hack it yourself.  It's the only real way that you're going to get such a grasp that you seek on cryptography.  Just like learning a new language (spoken or programming), you need complete immersion to catch on quickly.  Otherwise, you may spend a decade or two just asking questions on online forums until you believe you're satisfied with what you know.

Anyway, as requinix has said, just use password_hash(), use salts, use "random" numbers.  The idea is to take some piece of data, and run it through an irreversible algorithm that creates the hash.  Then, to verify data, push the input through the same algorithm to see if it results in the same hash.

Share this post


Link to post
Share on other sites

@Zane,

I was afraid you might say what you just did...  😞

For the record, no, I am not storing anyone's credit card details.  I am storing username, email address and hashed password at this point.

I actually do use Authorize.net although I haven't learned how to hook it up to my website - that is what i am working on now, building the ecommrce portion.

To my larger question...

I have a business rule that says, "There can be no more than two paid accounts associated with any given credit card.".

I *think*, but don't recall since I am learning about my payment gateway, that Authorize.net retains the payment details so I could do the above manually, but that wouldn't be practical, because I am trying to prevent one credit card holder from creating dozens of paid accounts.

I was thinking of taking the card type and last-4 and hashing them and then storing them in my database.  Then each time a person tries to purchase a new account, I would take the card type and last-4, hash it, and then compare that value to what is in my database.  if they match, then I would display an error message, "Only two accounts per cardholder".  If the hashes do NOT match, then I would allow the transaction to go through.

Hopefully that makes sense.

How dangerous and how much of a liability would it be to do that?

 

 

Share this post


Link to post
Share on other sites

Could you explain the scenario a bit more?

Only two accounts per cardholder.  So, a single user can purchase cards, and these are credit cards?  It's not so clear what your idea is.  Please elaborate.

Or maybe, it's a user cannot add more than two cards to their account.  

Share this post


Link to post
Share on other sites
2 minutes ago, Zane said:

Could you explain the scenario a bit more?

Only two accounts per cardholder.  So, a single user can purchase cards, and these are credit cards?  It's not so clear what your idea is.  Please elaborate.

Or maybe, it's a user cannot add more than two cards to their account.  

Sure.

First off, I am always open to suggestions on improving business processes and customer experience!

I have build a website that offers free content to all, and who those with a paid account, they get access to premium content and lots of other features like the ability to post comments, create profiles, pm each other, etc.  A customer gets access to these "premium" features through purchasing a paid subscription quite similar to an online news paper like the NY Times or LA Times.

The user would click on a "Subscribe" button, be shown a couple of different subscription plans, make a choice and check out.  During checkout, the user both creates and account on the spot and pays with a credit card for whatever subscription they choose (e.g. Platinum Plan for $50/year).

After doing some field research, people have told me that I should probably allow at least a couple of people to use the same credit card.  For example, maybe a mom buys a subscription, loves my site, and as a gift buys her daughter away in college a subscription too.

I am okay with maybe 2 accounts linked to one credit card (e.g. husband and wife, mother and daughter, etc.), however, I do NOT want to allow an unlimited number of accounts to a credit card.

Why?

Because I am attempting to use the credit card to link an online account on my website to a *real* person in real life.  If I let Mrs. Jones buy accounts for her husband and ten kids, then is user#7@mail.com started causing issues on my site, i wouldn't know if it was the cardholder or her husand or one of her 10 kids.

I could limit things to one account ("supermom@gmail.com") per cardholder name ("Mary Thompson") and credit card # ("4570 1111 2222 3333") but I'm thinking that might be a bit too draconian.  But as mentioned above, I also don't want an unlimited amount, because your credit card to me is as much about *trying* to establish ho you are in real life as it is to take your money!!

Make sense?

So ultimately I need a way to know that user#1 is linked to credit card #1 so if that customer comes back and tries to open 10 more accounts, then I can stop them.

Furthermore, if user#1 get kicked off of my site, and comes back and comes back later on and tries to register user#999 using the same credit card (and thus cardholder name) then I want to know that and STOP them from registering again.

Also make sense?

Of course I don't want to retain cardholder names and credit card #s, but if hashing is as hard to crack as a lot of people say, then i was wondering if storing a hash of the card type and last-4 (and possibly the cardholder name also) would be a way to accomplish what I need above, but also minimize my risk if there was an attack or data breach on my website.

Hopefully that give you a better picture of functionality that I'd really like to implement to help *me* control who is on my site!

Share this post


Link to post
Share on other sites
5 hours ago, SaranacLake said:

I *think*, but don't recall since I am learning about my payment gateway, that Authorize.net retains the payment details so I could do the above manually, but that wouldn't be practical, because I am trying to prevent one credit card holder from creating dozens of paid accounts.

If you are using Authorize.net, then you can setup Customer Payment Profiles, using their API.  You can then store (or relegate) the customer payment profile id to your users table in your database.  Then, you don't have to worry about storing credit cards info anywhere.

https://developer.authorize.net/api/reference/index.html#customer-profiles-get-customer-payment-profile

Maintaining reconciliation with Authorize.net customer profiles and your own database/table of users can allow you to do what you're attempting to do.  Using the API, you can send a request for the current users list of payment profiles.  If there are more than two profiles, then you can write in whatever logic you want in your PHP script, for instance, aborting the chance of a transaction from the user, showing them an error message.  Everything you need and more is available in their API.

 

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.