Detect duplicates without exposing underlying dataPassword Hashing: add salt + pepper or is salt enough?User authentication + database encryption with same passwordAPI message verification without storing private key?HMACs that have the same key and messageWhat's the recommended way to store at-rest, symmetrically encrypted customer data?How to store secret key used for hashing?Encrypt User specific Information without a password

Writing a letter of recommendation for a mediocre student

Is there any iPhone SE out there with 3D Touch?

Do multiple shower heads require multiple shower valves?

Is it right to extend flaps only in the white arc?

How use custom order in folder on Windows 7 and 10

Is it possible to encode a message in such a way that can only be read by someone or something capable of seeing into the very near future?

What did Tim Curry say in the movie Congo to Ernie Hudson after being insulted?

Is it impolite to ask for halal food when traveling to and in Thailand?

Would Taiwan and China's dispute be solved if Taiwan gave up being the Republic of China?

What's the next step in this Unequal (Futoshiki) puzzle?

How to manage expenditure when billing cycles and paycheck cycles are not aligned?

Co-Supervisor comes to office to help her students which distracts me

Do we know the situation in Britain before Sealion (summer 1940)?

Hilbert's hotel: why can't I repeat it infinitely many times?

A simple game that keeps track of the number of questions asked

Going to France with limited French for a day

What do you do if you have developments on your paper during the long peer review process?

Would there theoretically be an accompanying effect to something moving beyond the speed of light?

Designing a time thief proof safe

Is this Portent-like spell balanced?

How do pilots align the HUD with their eyeballs?

Is this a Sherman, and if so what model?

Hiking with a mule or two?

Do we have any particular tonal center in mind when we are NOT listening music?



Detect duplicates without exposing underlying data


Password Hashing: add salt + pepper or is salt enough?User authentication + database encryption with same passwordAPI message verification without storing private key?HMACs that have the same key and messageWhat's the recommended way to store at-rest, symmetrically encrypted customer data?How to store secret key used for hashing?Encrypt User specific Information without a password






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















We have a scenario where we need to prevent two users from using the same identifier. The identifier is sensitive (e.g. a social security number), so we do not want to store it in our DB. We just want to store some sort of hash that allows us to prevent subsequent users from using it again. And we want to do it securely, so that in the event that the database ever leaked, an attacker could not figure out the original values.



Is it possible to do securely? What is the recommended way?



Based on some research, it seems like a HMAC might work. If that's the case, what's the recommended algorithm? Should it be something slow (like scrypt with a fixed key salt), so that if the key is ever exposed, it's still difficult to uncover the values? Or is there no protection against that?










share|improve this question







New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 2





    scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

    – MechMK1
    8 hours ago






  • 2





    How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

    – Conor Mancone
    8 hours ago












  • @MechMK1 so you would use Argon2id with a fixed salt?

    – Peter Watts
    8 hours ago






  • 1





    @PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

    – MechMK1
    8 hours ago






  • 1





    @MechMK1, I assume it's because the use case requires comparing equality.

    – timuzhti
    8 hours ago

















3















We have a scenario where we need to prevent two users from using the same identifier. The identifier is sensitive (e.g. a social security number), so we do not want to store it in our DB. We just want to store some sort of hash that allows us to prevent subsequent users from using it again. And we want to do it securely, so that in the event that the database ever leaked, an attacker could not figure out the original values.



Is it possible to do securely? What is the recommended way?



Based on some research, it seems like a HMAC might work. If that's the case, what's the recommended algorithm? Should it be something slow (like scrypt with a fixed key salt), so that if the key is ever exposed, it's still difficult to uncover the values? Or is there no protection against that?










share|improve this question







New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 2





    scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

    – MechMK1
    8 hours ago






  • 2





    How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

    – Conor Mancone
    8 hours ago












  • @MechMK1 so you would use Argon2id with a fixed salt?

    – Peter Watts
    8 hours ago






  • 1





    @PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

    – MechMK1
    8 hours ago






  • 1





    @MechMK1, I assume it's because the use case requires comparing equality.

    – timuzhti
    8 hours ago













3












3








3


1






We have a scenario where we need to prevent two users from using the same identifier. The identifier is sensitive (e.g. a social security number), so we do not want to store it in our DB. We just want to store some sort of hash that allows us to prevent subsequent users from using it again. And we want to do it securely, so that in the event that the database ever leaked, an attacker could not figure out the original values.



Is it possible to do securely? What is the recommended way?



Based on some research, it seems like a HMAC might work. If that's the case, what's the recommended algorithm? Should it be something slow (like scrypt with a fixed key salt), so that if the key is ever exposed, it's still difficult to uncover the values? Or is there no protection against that?










share|improve this question







New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











We have a scenario where we need to prevent two users from using the same identifier. The identifier is sensitive (e.g. a social security number), so we do not want to store it in our DB. We just want to store some sort of hash that allows us to prevent subsequent users from using it again. And we want to do it securely, so that in the event that the database ever leaked, an attacker could not figure out the original values.



Is it possible to do securely? What is the recommended way?



Based on some research, it seems like a HMAC might work. If that's the case, what's the recommended algorithm? Should it be something slow (like scrypt with a fixed key salt), so that if the key is ever exposed, it's still difficult to uncover the values? Or is there no protection against that?







encryption hash sha hmac scrypt






share|improve this question







New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question







New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question






New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 8 hours ago









Peter WattsPeter Watts

161 bronze badge




161 bronze badge




New contributor



Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Peter Watts is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 2





    scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

    – MechMK1
    8 hours ago






  • 2





    How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

    – Conor Mancone
    8 hours ago












  • @MechMK1 so you would use Argon2id with a fixed salt?

    – Peter Watts
    8 hours ago






  • 1





    @PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

    – MechMK1
    8 hours ago






  • 1





    @MechMK1, I assume it's because the use case requires comparing equality.

    – timuzhti
    8 hours ago












  • 2





    scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

    – MechMK1
    8 hours ago






  • 2





    How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

    – Conor Mancone
    8 hours ago












  • @MechMK1 so you would use Argon2id with a fixed salt?

    – Peter Watts
    8 hours ago






  • 1





    @PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

    – MechMK1
    8 hours ago






  • 1





    @MechMK1, I assume it's because the use case requires comparing equality.

    – timuzhti
    8 hours ago







2




2





scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

– MechMK1
8 hours ago





scrypt is not a HMAC, scrypt is a Key-Derivation Function. A KDF is just fine for these purposes. I recommend Argon2id.

– MechMK1
8 hours ago




2




2





How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

– Conor Mancone
8 hours ago






How much "entropy" does your identifier have? For instance, if it is a social security number, then even a naive calculation suggests the total amount of entropy is low (9 digits = 1 billion possibilities), although actually entropy is much less than that even. As a result, hashing can be very ineffective, because brute-forcing is relatively easy, and extra care is needed. Is it actually a SSN, or is that just an example you picked?

– Conor Mancone
8 hours ago














@MechMK1 so you would use Argon2id with a fixed salt?

– Peter Watts
8 hours ago





@MechMK1 so you would use Argon2id with a fixed salt?

– Peter Watts
8 hours ago




1




1





@PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

– MechMK1
8 hours ago





@PeterWatts Why a fixed salt? That would make things worse. Argon2id has the ability to use a key, just like a HMAC would. Use a unique and sufficiently random salt, in combination with a long, sufficiently random key.

– MechMK1
8 hours ago




1




1





@MechMK1, I assume it's because the use case requires comparing equality.

– timuzhti
8 hours ago





@MechMK1, I assume it's because the use case requires comparing equality.

– timuzhti
8 hours ago










1 Answer
1






active

oldest

votes


















5
















I think you're not too far from a possible solution (aka using a modern KDF and effectively treating this like a password). However, there are some more considerations (which were already mentioned in comments):



  1. SSNs have very low entropy, which means that brute-force is an especially easy attack

  2. Since you need to find if the SSN has been used anywhere, you basically have to operate without a salt, which also makes brute-forcing substantially easier.

The combination of 1 & 2 would make a KDF a bad idea, even though it is your only option. As a result, finding a different business solution may be in order. However, I think there are a few steps you can take to mitigate the risk if SSN matching is an absolute requirement:



  1. Make sure and use a large "pepper". Peppers are less commonly used with passwords, so in case you aren't familiar: using a pepper basically means adding a large, constant, random string to the SSN before hashing which is not stored in the database. In this case I would use an especially long pepper. So in practice, this means that you create a 256 bit key that is not stored in the database or codebase but which is added to the SSN before hashing it. You would store it in an environment variable in your production server, or in your CD pipeline, so it is not readily accessible to developers (since they are sometimes the attacker, unfortunately). The reason for this is that if your database leaks but the attacker doesn't have the pepper, then they cannot bruteforce the SSNs (because bruteforcing the SSN would basically require first bruteforcing your 256 bit key, which is impossible).

  2. Use a very large cost function. All modern KDFs have a configurable cost function, that increases the time it takes to buid the hash (therefore making brute force harder). For something like this I'd set an even-higher-than-usual cost function. I'd probably tune it so that your systems take 1-2 seconds to hash the SSN+pepper. Go even higher if your users can tolerate the wait! This won't fix your bruteforce issue, but it will help.

  3. Anonymize these hashed SSNs! Basically, store them in a table by themselves with no way to associate them with any other data in the system (i.e. don't assign an autoincrementing id to this table or an entry time, since those might correlate with other tables). Have one table with just one column that is for this purpose and this purpose only. While the SSN alone is still personal information, it is much less dangerous to your users if it is leaked by itself without any further information. Having a table with just the hashed SSNs will still allow you to verify if an SSN has been entered before, so your overall goal can still be accomplished.

So again, your best bet might simply be to find a completely different way to do this without using SSNs. However, if this is an absolute business requirement, then the above steps can go a long way to securing your customer's personal data. Still, I would also check with regulatory requirements for your industry to make sure that you abide by all applicable rules.






share|improve this answer

























  • Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

    – Peter Watts
    2 hours ago











  • The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

    – John Wu
    2 mins ago














Your Answer








StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "162"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);







Peter Watts is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded
















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f218360%2fdetect-duplicates-without-exposing-underlying-data%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









5
















I think you're not too far from a possible solution (aka using a modern KDF and effectively treating this like a password). However, there are some more considerations (which were already mentioned in comments):



  1. SSNs have very low entropy, which means that brute-force is an especially easy attack

  2. Since you need to find if the SSN has been used anywhere, you basically have to operate without a salt, which also makes brute-forcing substantially easier.

The combination of 1 & 2 would make a KDF a bad idea, even though it is your only option. As a result, finding a different business solution may be in order. However, I think there are a few steps you can take to mitigate the risk if SSN matching is an absolute requirement:



  1. Make sure and use a large "pepper". Peppers are less commonly used with passwords, so in case you aren't familiar: using a pepper basically means adding a large, constant, random string to the SSN before hashing which is not stored in the database. In this case I would use an especially long pepper. So in practice, this means that you create a 256 bit key that is not stored in the database or codebase but which is added to the SSN before hashing it. You would store it in an environment variable in your production server, or in your CD pipeline, so it is not readily accessible to developers (since they are sometimes the attacker, unfortunately). The reason for this is that if your database leaks but the attacker doesn't have the pepper, then they cannot bruteforce the SSNs (because bruteforcing the SSN would basically require first bruteforcing your 256 bit key, which is impossible).

  2. Use a very large cost function. All modern KDFs have a configurable cost function, that increases the time it takes to buid the hash (therefore making brute force harder). For something like this I'd set an even-higher-than-usual cost function. I'd probably tune it so that your systems take 1-2 seconds to hash the SSN+pepper. Go even higher if your users can tolerate the wait! This won't fix your bruteforce issue, but it will help.

  3. Anonymize these hashed SSNs! Basically, store them in a table by themselves with no way to associate them with any other data in the system (i.e. don't assign an autoincrementing id to this table or an entry time, since those might correlate with other tables). Have one table with just one column that is for this purpose and this purpose only. While the SSN alone is still personal information, it is much less dangerous to your users if it is leaked by itself without any further information. Having a table with just the hashed SSNs will still allow you to verify if an SSN has been entered before, so your overall goal can still be accomplished.

So again, your best bet might simply be to find a completely different way to do this without using SSNs. However, if this is an absolute business requirement, then the above steps can go a long way to securing your customer's personal data. Still, I would also check with regulatory requirements for your industry to make sure that you abide by all applicable rules.






share|improve this answer

























  • Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

    – Peter Watts
    2 hours ago











  • The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

    – John Wu
    2 mins ago
















5
















I think you're not too far from a possible solution (aka using a modern KDF and effectively treating this like a password). However, there are some more considerations (which were already mentioned in comments):



  1. SSNs have very low entropy, which means that brute-force is an especially easy attack

  2. Since you need to find if the SSN has been used anywhere, you basically have to operate without a salt, which also makes brute-forcing substantially easier.

The combination of 1 & 2 would make a KDF a bad idea, even though it is your only option. As a result, finding a different business solution may be in order. However, I think there are a few steps you can take to mitigate the risk if SSN matching is an absolute requirement:



  1. Make sure and use a large "pepper". Peppers are less commonly used with passwords, so in case you aren't familiar: using a pepper basically means adding a large, constant, random string to the SSN before hashing which is not stored in the database. In this case I would use an especially long pepper. So in practice, this means that you create a 256 bit key that is not stored in the database or codebase but which is added to the SSN before hashing it. You would store it in an environment variable in your production server, or in your CD pipeline, so it is not readily accessible to developers (since they are sometimes the attacker, unfortunately). The reason for this is that if your database leaks but the attacker doesn't have the pepper, then they cannot bruteforce the SSNs (because bruteforcing the SSN would basically require first bruteforcing your 256 bit key, which is impossible).

  2. Use a very large cost function. All modern KDFs have a configurable cost function, that increases the time it takes to buid the hash (therefore making brute force harder). For something like this I'd set an even-higher-than-usual cost function. I'd probably tune it so that your systems take 1-2 seconds to hash the SSN+pepper. Go even higher if your users can tolerate the wait! This won't fix your bruteforce issue, but it will help.

  3. Anonymize these hashed SSNs! Basically, store them in a table by themselves with no way to associate them with any other data in the system (i.e. don't assign an autoincrementing id to this table or an entry time, since those might correlate with other tables). Have one table with just one column that is for this purpose and this purpose only. While the SSN alone is still personal information, it is much less dangerous to your users if it is leaked by itself without any further information. Having a table with just the hashed SSNs will still allow you to verify if an SSN has been entered before, so your overall goal can still be accomplished.

So again, your best bet might simply be to find a completely different way to do this without using SSNs. However, if this is an absolute business requirement, then the above steps can go a long way to securing your customer's personal data. Still, I would also check with regulatory requirements for your industry to make sure that you abide by all applicable rules.






share|improve this answer

























  • Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

    – Peter Watts
    2 hours ago











  • The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

    – John Wu
    2 mins ago














5














5










5









I think you're not too far from a possible solution (aka using a modern KDF and effectively treating this like a password). However, there are some more considerations (which were already mentioned in comments):



  1. SSNs have very low entropy, which means that brute-force is an especially easy attack

  2. Since you need to find if the SSN has been used anywhere, you basically have to operate without a salt, which also makes brute-forcing substantially easier.

The combination of 1 & 2 would make a KDF a bad idea, even though it is your only option. As a result, finding a different business solution may be in order. However, I think there are a few steps you can take to mitigate the risk if SSN matching is an absolute requirement:



  1. Make sure and use a large "pepper". Peppers are less commonly used with passwords, so in case you aren't familiar: using a pepper basically means adding a large, constant, random string to the SSN before hashing which is not stored in the database. In this case I would use an especially long pepper. So in practice, this means that you create a 256 bit key that is not stored in the database or codebase but which is added to the SSN before hashing it. You would store it in an environment variable in your production server, or in your CD pipeline, so it is not readily accessible to developers (since they are sometimes the attacker, unfortunately). The reason for this is that if your database leaks but the attacker doesn't have the pepper, then they cannot bruteforce the SSNs (because bruteforcing the SSN would basically require first bruteforcing your 256 bit key, which is impossible).

  2. Use a very large cost function. All modern KDFs have a configurable cost function, that increases the time it takes to buid the hash (therefore making brute force harder). For something like this I'd set an even-higher-than-usual cost function. I'd probably tune it so that your systems take 1-2 seconds to hash the SSN+pepper. Go even higher if your users can tolerate the wait! This won't fix your bruteforce issue, but it will help.

  3. Anonymize these hashed SSNs! Basically, store them in a table by themselves with no way to associate them with any other data in the system (i.e. don't assign an autoincrementing id to this table or an entry time, since those might correlate with other tables). Have one table with just one column that is for this purpose and this purpose only. While the SSN alone is still personal information, it is much less dangerous to your users if it is leaked by itself without any further information. Having a table with just the hashed SSNs will still allow you to verify if an SSN has been entered before, so your overall goal can still be accomplished.

So again, your best bet might simply be to find a completely different way to do this without using SSNs. However, if this is an absolute business requirement, then the above steps can go a long way to securing your customer's personal data. Still, I would also check with regulatory requirements for your industry to make sure that you abide by all applicable rules.






share|improve this answer













I think you're not too far from a possible solution (aka using a modern KDF and effectively treating this like a password). However, there are some more considerations (which were already mentioned in comments):



  1. SSNs have very low entropy, which means that brute-force is an especially easy attack

  2. Since you need to find if the SSN has been used anywhere, you basically have to operate without a salt, which also makes brute-forcing substantially easier.

The combination of 1 & 2 would make a KDF a bad idea, even though it is your only option. As a result, finding a different business solution may be in order. However, I think there are a few steps you can take to mitigate the risk if SSN matching is an absolute requirement:



  1. Make sure and use a large "pepper". Peppers are less commonly used with passwords, so in case you aren't familiar: using a pepper basically means adding a large, constant, random string to the SSN before hashing which is not stored in the database. In this case I would use an especially long pepper. So in practice, this means that you create a 256 bit key that is not stored in the database or codebase but which is added to the SSN before hashing it. You would store it in an environment variable in your production server, or in your CD pipeline, so it is not readily accessible to developers (since they are sometimes the attacker, unfortunately). The reason for this is that if your database leaks but the attacker doesn't have the pepper, then they cannot bruteforce the SSNs (because bruteforcing the SSN would basically require first bruteforcing your 256 bit key, which is impossible).

  2. Use a very large cost function. All modern KDFs have a configurable cost function, that increases the time it takes to buid the hash (therefore making brute force harder). For something like this I'd set an even-higher-than-usual cost function. I'd probably tune it so that your systems take 1-2 seconds to hash the SSN+pepper. Go even higher if your users can tolerate the wait! This won't fix your bruteforce issue, but it will help.

  3. Anonymize these hashed SSNs! Basically, store them in a table by themselves with no way to associate them with any other data in the system (i.e. don't assign an autoincrementing id to this table or an entry time, since those might correlate with other tables). Have one table with just one column that is for this purpose and this purpose only. While the SSN alone is still personal information, it is much less dangerous to your users if it is leaked by itself without any further information. Having a table with just the hashed SSNs will still allow you to verify if an SSN has been entered before, so your overall goal can still be accomplished.

So again, your best bet might simply be to find a completely different way to do this without using SSNs. However, if this is an absolute business requirement, then the above steps can go a long way to securing your customer's personal data. Still, I would also check with regulatory requirements for your industry to make sure that you abide by all applicable rules.







share|improve this answer












share|improve this answer



share|improve this answer










answered 7 hours ago









Conor ManconeConor Mancone

15.6k7 gold badges47 silver badges64 bronze badges




15.6k7 gold badges47 silver badges64 bronze badges















  • Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

    – Peter Watts
    2 hours ago











  • The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

    – John Wu
    2 mins ago


















  • Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

    – Peter Watts
    2 hours ago











  • The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

    – John Wu
    2 mins ago

















Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

– Peter Watts
2 hours ago





Ah! I had not considered that 3rd step. While it would be nice to know which user was associated with the re-used identifier, it's not critical, and seems like a reasonable tradeoff.

– Peter Watts
2 hours ago













The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

– John Wu
2 mins ago






The problem with storing the SSN with no identifying information is that it provides no recourse in the case of a collision. A hacker could (for example) enroll thousands of random SSNs in an application DoS attack, denying legitimate users the ability to use their own SSN if they are unfortunate enough to collide.

– John Wu
2 mins ago












Peter Watts is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded

















Peter Watts is a new contributor. Be nice, and check out our Code of Conduct.












Peter Watts is a new contributor. Be nice, and check out our Code of Conduct.











Peter Watts is a new contributor. Be nice, and check out our Code of Conduct.














Thanks for contributing an answer to Information Security Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f218360%2fdetect-duplicates-without-exposing-underlying-data%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480