Cách tìm kiếm cơ sở dữ liệu MySQL với các trường được mã hóa


15

Giả sử tôi cần mã hóa các trường bảng nhất định của sở dữ liệu MySQL . Ngoài ra, tôi cần tìm kiếm một số trường tôi đã mã hóa.

Làm thế nào một người sẽ tìm kiếm các lĩnh vực nào?

Giải mã từng bản ghi từng bước là không có tùy chọn: Giả sử tôi có nhiều hàng ngàn bản ghi. Sẽ mất quá nhiều thời gian và không gian để giải mã từng bản ghi và kiểm tra xem mỗi bản ghi có khớp với tìm kiếm hay không.

CẬP NHẬT 2012-09-07

Thêm các chi tiết khác vào lược đồ cơ sở dữ liệu sẽ ổn , vì tôi sắp triển khai một ứng dụng mới. Hơn nữa, tôi cần mở rộng các ứng dụng hiện đang chạy trong sản xuất. Nhưng ngay cả đối với những ứng dụng đó, việc thêm thông tin chi tiết sẽ ổn.

CẬP NHẬT 2012-09-08

Mã hóa là hạt nhân của câu hỏi này.

Các hạn chế truy cập, như được đề xuất bởi một số câu trả lời, đã được áp dụng - nhưng không phù hợp với yêu cầu chính thức để mã hóa dữ liệu.

Yêu cầu chính thức này không phảiTiêu chuẩn bảo mật dữ liệu công nghiệp thẻ thanh toán [PCI].

Câu trả lời:


11

Rõ ràng là chúng không có nghĩa là được xem, do đó tìm kiếm trên chúng sẽ có vấn đề.

Một mẹo tôi đã sử dụng trong quá khứ là băm dữ liệu được mã hóa trước khi mã hóa nó và lưu trữ hàm băm trong một cột được lập chỉ mục. Tất nhiên, điều này chỉ hoạt động nếu bạn đang tìm kiếm trên toàn bộ giá trị; giá trị một phần sẽ không có cùng hàm băm.

Bạn có thể có thể mở rộng điều này bằng cách tạo một chỉ mục băm "toàn văn", nếu bạn cần, nhưng nó có thể trở nên phức tạp rất nhanh.

ĐỊA CHỈ

Có ý kiến ​​cho rằng tôi nên thêm chú thích vào câu trả lời của mình cho một cuộc tranh luận khá dài trong cuộc trò chuyện về tính dễ bị tổn thương trước các cuộc tấn công từ điển, vì vậy tôi sẽ thảo luận về rủi ro bảo mật tiềm ẩn này cho phương pháp trên.

Tấn công từ điển: Tấn công từ điển là khi ai đó băm trước một danh sách các giá trị đã biết và so sánh các giá trị băm với cột băm của bạn trong cơ sở dữ liệu. Nếu họ có thể tìm thấy kết quả khớp, có khả năng giá trị đã biết thực sự là giá trị được băm (Mặc dù điều đó không xác định, vì băm không được đảm bảo là duy nhất). Điều này thường được giảm thiểu bằng cách băm giá trị bằng một "muối" ngẫu nhiên được nối hoặc thêm vào để hàm băm không khớp với từ điển, nhưng câu trả lời trên không thể sử dụng muối vì bạn mất khả năng tìm kiếm.

Cuộc tấn công này rất nguy hiểm khi xử lý những thứ như mật khẩu: nếu bạn tạo một từ điển băm mật khẩu phổ biến, sau đó bạn có thể nhanh chóng tìm kiếm bảng cho giá trị băm đó và xác định người dùng có mật khẩu đó và trích xuất thông tin xác thực để đánh cắp danh tính người dùng đó .

Nó ít nguy hiểm hơn đối với các mặt hàng có mức độ chính xác cao, như SSN, số thẻ tín dụng, GUID, v.v. (nhưng có những rủi ro khác nhau [đọc: pháp lý] liên quan đến việc lưu trữ những thứ này, vì vậy tôi không có xu hướng khuyên bạn nên lưu trữ chúng ).

Lý do cho điều này là để một cuộc tấn công từ điển hoạt động, bạn cần phải xây dựng sẵn một từ điển các giá trị có thể và băm của chúng. Về lý thuyết, bạn có thể xây dựng một từ điển của tất cả các SSN có thể (một tỷ hàng, giả sử tất cả các hoán vị định dạng đã bị xóa; hàng chục nghìn tỷ mục nhập cho thẻ tín dụng) ... nhưng đó thường không phải là điểm của một cuộc tấn công từ điển và về cơ bản trở nên tương đương với một cuộc tấn công vũ phu, nơi bạn đang điều tra một cách có hệ thống mọi giá trị.

Bạn cũng có thể tìm số SSN hoặc số thẻ tín dụng cụ thể , nếu bạn đang cố khớp SSN với một người. Một lần nữa, thường không phải là điểm của một cuộc tấn công từ điển, nhưng có thể làm được, vì vậy nếu đây là một rủi ro bạn cần tránh, câu trả lời của tôi không phải là một giải pháp tốt cho bạn.

Vì vậy, có bạn có nó. Như với tất cả các dữ liệu được mã hóa, nó thường được mã hóa vì một lý do, vì vậy hãy lưu ý đến dữ liệu của bạn và những gì bạn đang cố gắng bảo vệ dữ liệu đó.


Thảo luận về câu trả lời này đã được chuyển sang trò chuyện .
Paul White phục hồi Monica

5

Bạn có thể muốn xem CryptDB . Đó là một mặt trước cho MySQL và PostgreSQL cho phép lưu trữ và truy vấn dữ liệu được mã hóa trong suốt. Nó hoạt động bằng cách mã hóa và giải mã dữ liệu khi nó đi qua giữa ứng dụng và cơ sở dữ liệu, viết lại các truy vấn để hoạt động trên dữ liệu được mã hóa. và bằng cách điều chỉnh linh hoạt chế độ mã hóa của từng cột để chỉ hiển thị nhiều thông tin cần thiết cho các truy vấn mà ứng dụng sử dụng.

Các phương thức mã hóa khác nhau được CryptDB sử dụng bao gồm:

  • RND , sơ đồ mã hóa bảo mật IND-CPA hoàn toàn không rò rỉ thông tin về dữ liệu (ngoại trừ sự hiện diện của nó và, đối với các loại độ dài thay đổi, độ dài) nhưng chỉ cho phép lưu trữ và truy xuất, không có truy vấn.

  • DET , một biến thể của RND mang tính xác định, sao cho hai giá trị giống hệt nhau (trong cùng một cột) mã hóa vào cùng một bản mã. Hỗ trợ truy vấn bình đẳng của mẫu WHERE column = 'constant'.

  • OPE , một chương trình mã hóa bảo toàn trật tự hỗ trợ các truy vấn bất bình đẳng như WHERE column > 'constant'.

  • HOM , một sơ đồ mã hóa đồng hình một phần (Paillier) cho phép cộng các giá trị được mã hóa lại với nhau bằng cách nhân các bản mã. Hỗ trợ SUM()truy vấn, bổ sung và tăng dần.

  • TÌM KIẾM , một chương trình hỗ trợ tìm kiếm từ khóa của biểu mẫu WHERE column LIKE '% word %'.

  • THAM GIAOPE-THAM GIA , các biến thể của DET và OPE cho phép các giá trị trong các cột khác nhau được so sánh với nhau. Hỗ trợ bình đẳng và phạm vi tham gia tương ứng.

Sức mạnh thực sự của CryptDB là nó điều chỉnh phương thức mã hóa của từng cột một cách linh hoạt cho các truy vấn mà nó nhìn thấy, do đó các lược đồ chậm và / hoặc kém an toàn hơn chỉ được sử dụng cho các cột yêu cầu chúng. Ngoài ra còn có nhiều tính năng hữu ích khác, chẳng hạn như khóa mã hóa cho mật khẩu người dùng.

Nếu bạn quan tâm, bạn nên xem qua các bài viết được liên kết từ trang web CryptDB, đặc biệt là "CryptDB: Bảo vệ bí mật với xử lý truy vấn được mã hóa" của Popa, Redfield, Zeldovich và Balakrishnan ( SOSP 2011 ). Những bài báo này cũng mô tả các sự đánh đổi hiệu suất và bảo mật khác nhau liên quan đến việc hỗ trợ các loại truy vấn khác nhau chi tiết hơn.


1
It works by encrypting and decrypting data as it passes between the application and the database: Chắc chắn điều này có thể gây ra sự cố nếu dữ liệu đang được tìm kiếm đã có trong cơ sở dữ liệu (được mã hóa) nhưng rõ ràng chính truy vấn tìm kiếm cơ sở dữ liệu chỉ được chuyển đến CryptDB (và sau đó được mã hóa?). Tôi không thể hiểu làm thế nào phương pháp này có thể hiệu quả?
Martin

3

Tôi không hiểu tại sao các câu trả lời hiện tại chưa đặt câu hỏi đầy đủ cho các yêu cầu, vì vậy tôi sẽ hỏi và để lại câu trả lời.

Những lý do kinh doanh là gì? Dữ liệu nào bạn cần mã hóa và tại sao? Nếu bạn đang tìm kiếm sự tuân thủ PCI, tôi có thể viết một bài luận.

Câu hỏi về yêu cầu của bạn:

  • Bạn sẽ cần phải trả lại một tồn tại / không tồn tại như là kết quả, hoặc dữ liệu thực tế?
  • Bạn có yêu cầu khả năng THÍCH '% OMG_SEKRIT%' không?
  • Ai không thể xem dữ liệu và tại sao?

Bảo mật RDBMS thường được thực hiện trên cơ sở quyền được thi hành bởi người dùng / vai trò. Dữ liệu thường được mã hóa bởi RDBMS trên đĩa, nhưng không phải trong chính dữ liệu cột, vì điều đó thực sự không có ý nghĩa gì đối với một ứng dụng được thiết kế để lưu trữ và truy xuất dữ liệu một cách hiệu quả.

Hạn chế bởi người dùng / vai trò / api. Mã hóa trên đĩa. Nếu bạn đang lưu trữ dữ liệu quan trọng hơn, tôi muốn biết lý do tại sao bạn sử dụng MySQL.


Chủ yếu, tôi cần tìm tồn tại / không tồn tại và sau đó xác định vị trí hồ sơ cụ thể. Hỗ trợ THÍCH đầy đủ sẽ ổn. Nhưng tôi tự hỏi, rằng bất cứ điều gì nhiều hơn so với kết hợp các từ sẽ có thể. Người dùng được ủy quyền được phép xem dữ liệu. Ứng dụng giải mã những mục đó, một người dùng hợp pháp có quyền xem. Các lược đồ cơ sở cho phép là không có tùy chọn.
SteAp

Tiêu chí cho "dữ liệu quan trọng hơn là gì?"
arcanine

2

Tôi đang xem xét điều này và bắt gặp câu hỏi của bạn. Tôi đang nghiêng về cách tiếp cận được nêu trong phần 5.4 của bài viết "Các kỹ thuật thực tế để tìm kiếm dữ liệu được mã hóa" http: //www.cs.ber siêu.edu / ~ dawnsong / con / se.pdf

Ý chính cơ bản là tạo ra một chỉ mục chứa các từ khóa được mã hóa có trong tài liệu tìm kiếm được mã hóa. Bí quyết là cũng mã hóa các vị trí trong tài liệu (hoặc cơ sở dữ liệu) nơi có các từ khóa đó.


1

Về mặt lập trình, một giải pháp hiệu quả là

  1. lấy TẤT CẢ các bản ghi cho CHỈ lĩnh vực bạn đang tìm kiếm với id bản ghi
  2. giải mã chúng thành một bảng tạm thời
  3. thực hiện tìm kiếm dựa vào bảng đó
  4. sử dụng id để lấy toàn bộ hồ sơ (tất cả các trường) phù hợp với tiêu chí tìm kiếm
  5. giải mã chúng và trả lại cho người dùng

Vấn đề là 1 và 4 là các bộ dữ liệu nhỏ hơn đáng kể so với truy xuất và giải mã tất cả các trường của tất cả các bản ghi lúc đầu.

Mong rằng sẽ giúp.


Các bảng tạm thời trong bản rõ tương đối dễ dàng để lấy và đọc, phá vỡ máy chủ vào đúng thời điểm hoặc chỉ đơn giản là sao chép temp/thư mục và đập, các giá trị văn bản cho toàn bộ cột ở đây, đây không phải là cách vận hành an toàn
Martin

1

Điều này có thể với chức năng tìm kiếm đầy đủ bằng cách sử dụng các chức năng mã hóa nội bộ của MYSQL.

Đây là một ví dụ:

!!! TÔI ĐANG SỬ DỤNG MYSQL ENCODE () TẠI ĐÂY ĐỂ ĐƠN GIẢN, MYSQL_ENCODE NGAY BÂY GIỜ ĐƯỢC TƯ VẤN, SỬ DỤNG MỘT TRONG NHỮNG CHỨC NĂNG MYSQL NỘI BỘ KHÁC !!!

UPDATE my_table
SET field=ENCODE('my_data', 'my_password')
WHERE ID=1;

SELECT DECODE(field, 'my_password') as field FROM my_table
WHERE field LIKE 'data';

Như nhận xét trên cho thấy, KHÔNG sử dụng ENCODE (), sử dụng một trong các chức năng mã hóa khác mà tôi chỉ sử dụng ENCODE trong ví dụ này do tính đơn giản của nó

Nếu bạn đang thực hiện việc này trong một ứng dụng như php, bạn có thể thực hiện việc này trong cổng db hoặc các lớp kho lưu trữ của mình bằng cách lưu trữ một danh sách / mảng của các cột được mã hóa của mỗi bảng trong lớp cổng tương ứng của nó.

class UserGateway
{
    protected $encrypted_fields = array(
        'username',
        'email'
    );

    public function get($fields, ...)
    {
        foreach ($fields as $k => $field) {
            if (in_array($field, $fields)) {
                $fields[$k] = $this->decodeSelect($field);
            }
        }

        $sql = 'SELECT '.implode(',', $fields);

        //......
    }

    protected function decodeSelect($field)
    {
        return "DECODE($field, $pass) AS $field";
    }
}

Tất nhiên đây là mã rất thô và không an toàn không nên được sử dụng trong sản xuất mà không cải thiện đáng kể. Nhưng nó nên phục vụ mục đích của nó trong việc đưa ra ý tưởng chung.


-1

Giả sử bạn đang tìm kiếm trong SQL và dựa trên toàn bộ giá trị và không phải một phần (ví dụ: THÍCH 'value%') ... khi chụp dữ liệu tìm kiếm, mã hóa dữ liệu đó bằng thuật toán tương tự được sử dụng khi dữ liệu được mã hóa và tìm kiếm dữ liệu đó.

Ví dụ:

Điều gì sẽ là:

SELECT FieldA, FieldB 
FROM Table1 
WHERE FieldC = 'Value'

Thay vào đó có thể trông giống như:

SELECT FieldA, FieldB 
FROM Table1 
WHERE FieldC = 'hsk&%67ghhks83'

1
Mã hóa Decent sẽ hoạt động với giá trị muối, vì vậy, ví dụ, nếu bạn có một loại muối duy nhất cho mỗi hàng, thì mỗi hàng muối sẽ cần được sử dụng trên chuỗi tìm kiếm, điều này sẽ trở nên phức tạp và tốn kém, khá nhanh
Martin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.