You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Google/Tink的密码加密数据库存储问题咨询

Fixing Encrypted Password Storage Issues with Google Tink

Hey there! I see you're running into trouble when storing encrypted passwords from Google Tink in your database—let's break this down and fix it.

The Root Problem

When you encrypt a password with Tink, you get a raw byte[] (binary data). If you directly convert this byte array to a string using something like new String(ciphertext), you're asking Java to interpret those binary bytes as characters using a default encoding (like UTF-8). The issue? Not all binary values map to valid UTF-8 characters, so this conversion will corrupt or lose data. When you pull that corrupted string back from the database, you won't be able to decrypt it properly.

The Solution: Encode Binary Data to a Safe String Format

You need to convert the raw binary ciphertext into a string using an encoding that preserves all data. Two common, reliable options are Base64 or Hexadecimal (Hex) encoding—both turn binary data into printable ASCII characters that databases handle perfectly.

Option 1: Base64 Encoding (Most Common)

Base64 is widely supported and produces relatively compact strings. Here's how to integrate it with your existing Tink code:

import java.util.Base64;

// After encrypting to get ciphertext byte[]
String ciphertextStr = Base64.getEncoder().encodeToString(ciphertext);
// Store ciphertextStr in your database as a regular string

// When retrieving from the database to decrypt
String storedCiphertext = ...; // Get from DB
byte[] ciphertextBytes = Base64.getDecoder().decode(storedCiphertext);
byte[] plaintext = aead.decrypt(ciphertextBytes, aad); // Use same AAD as encryption!

Option 2: Hexadecimal Encoding

Hex encodes each byte as two hex characters (0-9, A-F), which is more verbose but easy to read if you ever need to inspect the data. Using Java's built-in tools:

import javax.xml.bind.DatatypeConverter;

// Encrypt then convert to Hex string
String ciphertextHex = DatatypeConverter.printHexBinary(ciphertext);
// Store ciphertextHex in your database

// Retrieve and convert back to byte[]
String storedHex = ...; // Get from DB
byte[] ciphertextBytes = DatatypeConverter.parseHexBinary(storedHex);
byte[] plaintext = aead.decrypt(ciphertextBytes, aad);

Critical Extra Notes

  • Never skip AAD: Always use the same Associated Authenticated Data (AAD) value during encryption and decryption. A great practice is to use a unique identifier for the user (like their user ID) as AAD—this adds an extra layer of security, ensuring a ciphertext can only be decrypted for the intended user.
  • Secure your keys: Your KeysetHandle contains sensitive encryption keys. Never hardcode it, store it in plaintext, or commit it to version control. Use Tink's built-in key management tools (like KeysetManager) or integrate with a Key Management Service (KMS) to encrypt and store your keys securely.

内容的提问来源于stack exchange,提问作者Manish Mehta

火山引擎 最新活动