Tôi đã tạo một dịch vụ tiền điện tử bằng AES-GCM để mã hóa dữ liệu nhạy cảm trong cơ sở dữ liệu. Đầu tiên, tôi đang tạo khóa mật mã từ mật khẩu (có thể sẽ được lưu trữ trong Kubernetes Secrets) bằng cách sử dụng Rfc2898DeriveBytes. Sau đó, chuyển khóa này sang phiên bản AesGcm.Bạn có thể tìm thấy việc thực hiện xuống dưới đây.
lớp công khai CryptoService : ICryptoService, IDisposable
{
AesGcm _aesGcm chỉ đọc riêng tư;
dịch vụ tiền điện tử công khai (mật khẩu chuỗi, chuỗi muối)
{
byte[] key = new Rfc2898DeriveBytes(mật khẩu, Encoding.UTF8.GetBytes(salt), 200000, HashAlgorithmName.SHA512).GetBytes(32);
//Nhận khóa mã hóa dữ liệu đã mã hóa được tạo ngẫu nhiên một cách an toàn từ Azure Vault.
chuỗi mã hóaEncryptionKey = AzureVault.GetDataEncryptionKey();
byte[] EncryptionKey = AzureVault.Decrypt(encryptedEncryptionKey, key);
_aesGcm = new AesGcm(encryptionKey);
}
Mã hóa chuỗi công khai (chuỗi văn bản thuần túy)
{
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
int nonceSize = AesGcm.NonceByteSizes.MaxSize;
int tagSize = AesGcm.TagByteSizes.MaxSize;
int cipherSize = plainBytes.Length;
// Kết hợp để mã hóa dễ dàng hơn
int mã hóaDataLength = 4 + nonceSize + 4 + tagSize + cipherSize;
Khoảng cách<byte> dữ liệu mã hóa = mã hóaDataLength <1024? stackalloc byte[encryptedDataLength] : byte mới[encryptedDataLength].AsSpan();
BinaryPrimitives.WriteInt32LittleEndian(encryptedData.Slice(0, 4), nonceSize);
BinaryPrimitives.WriteInt32LittleEndian(encryptedData.Slice(4 + nonceSize, 4), tagSize);
var nonce =cryptedData.Slice(4, nonceSize);
thẻ var = mã hóaData.Slice(4 + nonceSize + 4, tagSize);
var cipherBytes =cryptedData.Slice(4 + nonceSize + 4 + tagSize, cipherSize);
RandomNumberGenerator.Fill(nonce);
_aesGcm.Encrypt(nonce, plainBytes.AsSpan(), cipherBytes, thẻ);
trả về Convert.ToBase64String(encryptedData);
}
giải mã chuỗi công khai (chuỗi cipherText)
{
Span<byte>cryptedData = Convert.FromBase64String(cipherText).AsSpan();
int nonceSize = BinaryPrimitives.ReadInt32LittleEndian(encryptedData.Slice(0, 4));
int tagSize = BinaryPrimitives.ReadInt32LittleEndian(encryptedData.Slice(4 + nonceSize, 4));
int cipherSize = mã hóaData.Length - 4 - nonceSize - 4 - tagSize;
var nonce =cryptedData.Slice(4, nonceSize);
thẻ var = mã hóaData.Slice(4 + nonceSize + 4, tagSize);
var cipherBytes =cryptedData.Slice(4 + nonceSize + 4 + tagSize, cipherSize);
Span<byte> plainBytes = cipherSize <1024? stackalloc byte[cipherSize] : byte mới[cipherSize];
_aesGcm.Decrypt(nonce, cipherBytes, tag, plainBytes);
trả về Encoding.UTF8.GetString(plainBytes);
}
}
Đây là câu hỏi của tôi. Tôi tự hỏi liệu việc triển khai này có đủ an toàn hay không vì tôi không phải là chuyên gia về bảo mật. Tôi có thiếu một điểm hoặc lỗ hổng bảo mật ngoại trừ bảo mật mật khẩu không? Mọi lời khuyên và đề xuất sẽ được đánh giá rất cao.
Cảm ơn.