Tôi đang làm việc với một nhóm nhà phát triển đang triển khai mã hóa ở trạng thái nghỉ ở cấp ứng dụng. Nó dành cho các trường đặc biệt nhạy cảm bên trong RDB. (Bộ lưu trữ DB cơ bản có một lớp mã hóa bổ sung, nhưng điều đó không có chủ đề ở đây.) Chúng tôi đang sử dụng Spring's AesBytesMã hóa và các lớp liên quan cho điều đó.
Chúng tôi vẫn chưa giải quyết hoàn toàn việc xoay phím và tôi đang điều tra cách thực hiện điều đó một cách an toàn. Chúng tôi muốn sử dụng một công cụ xoay phím riêng biệt sẽ chạy tách biệt với ứng dụng sử dụng dữ liệu. Công cụ xoay khóa đó sẽ truy cập DB một cách không đồng bộ và thực hiện mã hóa lại theo từng phần nhỏ. (Không phải trong một giao dịch DB duy nhất sẽ mã hóa lại tất cả dữ liệu.)
Để làm như vậy, chúng tôi dự định rằng ứng dụng có thể được định cấu hình bằng nhiều phím (tốt, hai) cùng một lúc. Nó sẽ luôn sử dụng khóa đầu tiên để mã hóa dữ liệu mới. Nhưng nó có thể giải mã dữ liệu cũ bằng một trong hai khóa, tùy thuộc vào việc công cụ xoay khóa đã mã hóa lại trường cụ thể hay chưa.
Bây giờ, câu hỏi đặt ra là liệu chúng ta có cần lưu trữ siêu dữ liệu phiên bản khóa bổ sung trong DB hay không? Điều đó sẽ cho ứng dụng biết khóa giải mã nào sẽ được sử dụng cho bất kỳ đoạn dữ liệu nào.
Thay vào đó, tôi hy vọng sẽ giải quyết được vấn đề đó bằng cách dựa vào một số tổng kiểm tra biểu mẫu. Ứng dụng sẽ lần lượt thử các khóa giải mã cho đến khi nhận được giá trị giải mã không phá vỡ tổng kiểm tra.
Imho, AesBytesEncryptor của Spring có thể đã cung cấp tất cả những gì chúng tôi cần. Nhưng độ tin cậy sẽ phụ thuộc vào chế độ chúng ta sử dụng. Đây là suy nghĩ của tôi về hai chế độ được hỗ trợ:
Chế độ AES/CBC/PKCS5Đệm:
Không có tổng kiểm tra per-se, nhưng phần đệm có thể sẽ bị hỏng khi cố gắng giải mã bằng khóa sai. Tuy nhiên, điều này phụ thuộc vào kích thước của phần đệm, phụ thuộc vào kích thước dữ liệu văn bản gốc. Trường hợp xấu nhất có thể chỉ có 1byte đệm. Vì vậy, cơ hội để nhấn đúng phần đệm với khóa giải mã sai có thể lên tới 1/256. Điều đó dường như quá rủi ro để dựa vào.
Chế độ AES/GCM/NoPadding:
Ở đây, "thẻ xác thực" GCM đóng vai trò là một dạng tổng kiểm tra. Theo như tôi hiểu thì AES luôn dài 128 bit (16 byte). Điều đó có nghĩa là cơ hội chạm vào thẻ xác thực hợp lệ với khóa giải mã sai là khoảng 1/(2^128).Điều đó thực tế là không bao giờ, vì vậy tôi nghĩ rằng nó sẽ phù hợp với ứng dụng của chúng tôi.
Các giả định trên có đúng không? Tôi đã làm gì sai?
Bạn có nghĩ rằng nó đủ mạnh để thử lần lượt nhiều khóa giải mã trong quá trình xoay khóa, khi sử dụng AES/GCM/NoPadding không? Hay rốt cuộc chúng ta có cần lưu trữ thông tin phiên bản chính cùng với dữ liệu được mã hóa không?
Hoặc, có cách nào tốt hơn để giải quyết xoay vòng khóa trong kịch bản của chúng tôi không?