问题
I have a problem similar to the following:
A person begins working as a consultant for "Company A". Their HR person sets up an account for them. A record is created for the person in a "person" table and a "person-company" one.
The person is also working for "Company B" (which Company A may or may not know about). When Company B enters their info they should NOT create a record in "person" but SHOULD create one in "person-company".
The person is required to do training for the state, so if they are logged into either company's site when they do the training, we want the total hours to remain with the person.
I can set up a PK for the person table the joins them to each company, but I think I need something like a hash of the person's SSN with some extra "xyz" tacked on to be able to do a lookup. Company B would have the SSN for the person, which should be universal.
Questions:
1) Is there some other method to join that one of you think would work better?
2) If I do go with a hashed SSN approach, what's the best encryption to use for MySQL/PHP for one-way encryption?
I read elsewhere that a public/private key solution may be best, but since the person is not setting up their own account initially I'm not sure how this would work.
Thanks
回答1:
I think this article may be very relevant to what you are doing. If indeed you wish to "anonymize" the SSNs for security reasons and legal liability, then simply hashing them is not enough.
Just hashing them would be a completely deterministic process, so to effectively "mask" individual SSNs, the process needs to be randomized. Otherwise you could simply brute force through all possible combinations of SSNs (which would be much less work required than trying to brute force the hash function) and look for a matching value.
To see why this holds take the most simplistic example that a SSN could just take on two values, 0 and 1. Regardless of the quality and strength of the hash function, in the end there will only be two possible outcomes and it's easy to see which is which.
It's the old game of why you shouldn't hash e.g. passwords directly without performing some preprocessing on them first. The underlying data just doesn't contain enough entropy and will therefore be an easy target for lookups in a precomputed table.
The minute your SSNs become private and confidential (they are not in every country, so forgive my stupid question in the comments :), the same best practices that are also used for password storage should also be applicable to your particular case, i.e. a slow adaptive hashing algorithm that compensates for the lack of initial entropy such as bcrypt, scrypt and PBKDF2 (which was already recommended by Marcus Adams).
回答2:
PKI would be overly complicated for your use case, and could possibly increase the number of security holes in the system. Using hashed SSN's would be quick and fairly portable - I would recommend SHA-2. It is infact recommended as a part of the Federal Information Processing Standard.
回答3:
For hashing to be secure, you really need a random salt in order to prevent rainbow attacks. However, a random salt would preclude the ability to use it as a lookup value.
Salting the hash with the person's last name would be better than nothing, and it would still allow you to perform the lookup.
PKI algorithms are generally weaker than a good symmetric algorithm using the same key length, so if you're thinking about using a reversible encryption algorithm, you wouldn't want to use PKI.
A randomly salted one way hashing algorithm would be ideal, and SHA1 and above should be fine, though PBKDF2 would be better.
SHA2 is supported in MySQL 5.5+, and both SHA1 and SHA2 return a hex encoded hash value, so it could be stored in an indexed fixed-length CHAR column.
来源:https://stackoverflow.com/questions/10486025/alternative-to-hashed-ssn-as-a-key-in-mysql