0

Premise: I'm asked to develop a system that will trace sensitive data. The data are gathered by an intermediate operator (let's call him IO) on an office terminal. The final user (EU) will show up to the office, identify itself via an ID document, the operator will acquire the information and send it to the system. On request, given the not anonymous ID, the IO be able to consult the history of all the information acquired for that ID.

Objective: store the data on a centralized server in a completely anonymous way using an anonymous ID as an alias of the real ID. I want to make hard even for the technical operators of the server to retrieve the original ID.

My solution since now: as a first step toward the solution I thought of generating a salt hash starting from the password inserted by the IO, and use this salt for hashing the not anonymous ID, then send to the server the hashed ID instead of the real ID (there is the possibility of a hash collision, but, in my scenario it is an acceptable risk).

The problem is that every time the IO will change the password, he will lose access to the history of all the ID inserted (the same, not anonymous ID, will be translated as x before password change and as y after).

An improvement should be that the system will generate a salt on the IO machine at first login attempt, crypt it using the IO password and store it on the server. The salt will be retrieved at every future access, decrypted on the IO machine and used to generate the ID. If the user will change his password it will send, during the normal change password procedure also the hash encrypted with the new password. If the user forgot the password, the procedure to generate a new one will be started and IO will lose access to the history (this is acceptable given the sensitive nature of this data, it will be IO responsibility to store his password in the safest way possible).

At the moment I see a flawless on this procedure, on server side, every time a new encrypted hash will be sent to the server, technical operator will have access to a sequence of encrypted hash, they know this is the same number encrypted with different passwords, this will be a useful information tha will help to crack the salt. How can I protect against this? There are others weaknesses?

But there is more: the perfect solution will allow 2 or more IO to gather data for the same, not anonymous ID, and store it on the server with the same anonymous ID not allowing server operator to retrieve the original ID.

There is a way to achieve this result?

Thank you

PS: as observed in one of the answers one of the challenges of this project is that not anonymous ID are very limited (in the order of billions) and can be easily enumerated.

1

It depends on a few things:

  • How large is the input keyspace
  • How secure are the systems that will be processing this data
  • How much money do you have to spend

The size of the keyspace -- the original ID -- is important because a large keyspace can let you use a simple algorithm. For example, if you want to anonymize email addresses, a simple SHA-X hash will suffice, because the email addresses are long and have an effectively infinite number of possible values.

On the other hand, if you want to anonymize US social security numbers, the hash won't suffice, because it's trivial to enumerate all possible values.

So you can add a salt, which increases the size of the input values. But as you noted, you can't let the salt change for the same ID or you lose the ability to track that ID over time. But then you have to manage the salt that belongs with each ID, so that it can be re-applied each time.

Here's a bad idea: hardcode a long salt into your application, and use the same salt for each ID. This will guarantee anonymity only as long as nobody is able to discover the salt. Once they do, of course, they can easily enumerate all hash values.

But it does point to a better solution: externalize the hashing, to a system that you don't control. You would send off the actual ID to this external system, and it would return you a hash value. If your systems are compromised, it doesn't help the attacker; they would need to compromise the hash service as well.

Which brings me to the standard implementation: a hardware security module. This module plugs into your computer and provides the hashing operation. An attacker would have to physically access the module, and they're designed to prevent physical access.

The drawback is that they're expensive, and require you to physically manage (and secure!) the machines that use them. But if you want guarantees, that's where you'll end up.

  • It might be possible to do this with the TPM that's included with most modern PC's. – Robert Harvey Nov 9 '17 at 19:12
  • You have got the point. The ID I want to anonymize has a limited keyspace. This is another challenge of this project. Do you have any idea on how I can share a "salt service" (software externalized or hardware) so that history of an ID can be tracked by all the user of the system and still remain anonymous? Thank you. – Fabio Persi Nov 9 '17 at 22:10
0

If your input keyspace is too small there's nothing you can do about brute forcing it. About all you can hope for is to make it harder. My inclination would be to do something like make the anonymous ID simply a bcrypt hashing of the non-anonymous ID but with a very high work factor--pick a number that causes say 10 seconds of work.

Also, is there any other information in the non-anonymous record that's not in the anonymous one? Say, perhaps, a birth date? That can't change, although it's remotely possible that an error would be caught and fixed. Adding that would greatly increase your keyspace.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.