I'm planning to use tink to encrypt records stored in a database. I also plan to hash specific values from the records in order to be able to find records by field values. In order to avoid rainbow table attacks, I plan to store a salt with each key, and use that salt for the hashes. I want to encrypt the salt with each key so process we implement to re-encrypt records will update the searchable hash digests.

My simple question, then, is how do I associate and encrypt a salt with each Tink key in a keyset? I can think of a few options:

  1. Store it separately, but reference each key ID. Something like:

        "keyset": {
            "encryptedKeyset": "Encrypted keyset",
            "keysetInfo": {
                "primaryKeyId": 3330993843,
                "keyInfo": ["key objects"]
        "hash": {
            "algo": "SHA256",
            "encryptedSalts": "Encrypted map of each key ID to a random salt"

    This is do-able with the Tink Go library, which would manage the config in the "ketyset", and which the key management app we write would reference to make sure there were salts for each key (enabled) ID. But it would be nicer if the salt could just be a part of each key in the encrypted keyset.

  2. Just use something else from the keys as-is as the salt, perhaps the first few bytes of a hash of each key, or just the ID. This would require less customization of the configuration, but then the salt wouldn't be much of a secret (not encrypted). Unless there's a way to get the raw key data to derive a salt from, but there are good reason's they're not readily accessible from the Tink Go library.

  3. Decouple the hash index rotation from the encryption rotation and store the salts completely separately, perhaps even using a tink mac. This would require two processes to handle record updates, however: one to re-encrypt records from an old key to a new, and one from an old salt to a new. Which seems redundant, to be honest, and likely to generate more churn in the database.

None of these are ideal, but perhaps I'm overlooking another option?

Of course the less simple question might be: is this even a good idea? Or is there a better pattern for managing hash indexing to avoid rainbow table attacks? I get that using a salt like a secret might seem a bit weird But finding a record requires a deterministic value, so we can't salt and hash like we would a password.



Your Answer

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