2010-03-23 25 views
5

Quan tâm của tôi là các khóa mật mã và bí mật được quản lý bởi bộ thu gom rác có thể được sao chép và di chuyển xung quanh trong bộ nhớ mà không cần số không.Làm cách nào để đảm bảo rằng đối tượng Java (chứa tài liệu mã hóa) được zeroized?

Là một giải pháp khả thi, nó là đủ để:

public class Key { 
    private char[] key; 
    // ... 
    protected void finalize() throws Throwable { 
    try { 
     for(int k = 0; k < key.length; k++) { 
     key[k] = '\0'; 
     } 
    } catch (Exception e) { 
     //... 
    } finally { 
     super.finalize(); 
    } 
    } 
    // ... 
} 

EDIT: Xin lưu ý rằng vấn đề của tôi là liên quan đến không chỉ zeroization của chính thức (tham chiếu) bản sao của đối tượng, mà còn bất kỳ bản cũ các người thu gom rác có thể đã thực hiện trong khi nó xáo trộn bộ nhớ xung quanh cho không gian và tốc độ hiệu quả.

Ví dụ đơn giản nhất là GC đánh dấu và quét, nơi các đối tượng được đánh dấu là 'tham chiếu' và sau đó tất cả các đối tượng đó được sao chép sang một vùng khác. Phần còn lại là rác và do đó chúng được thu thập. Khi bản sao xảy ra, điều đó có thể để lại dữ liệu khóa còn lại không được quản lý bởi bộ thu gom rác (vì dữ liệu 'chính thức' nằm trong vùng mới).

Kiểm tra litmus cho điều này sẽ là nếu bạn sử dụng khóa trong mô-đun mã hóa, zeroize khóa, sau đó kiểm tra toàn bộ không gian quy trình JVM, bạn nên không phải tìm khóa đó.

+0

Tôi đã xem xét xung quanh, nhưng tôi không tìm thấy cách truy cập dữ liệu GC. Tôi muốn trả lời rằng loại bỏ các tham chiếu giữa các thuộc tính và giá trị của nó, không có cách nào để truy cập nó một lần nữa, nhưng tôi không shure, như bạn đã có nghi ngờ này. – marionmaiden

+0

Về cơ bản không có cách nào (hiện tại) để làm những gì bạn muốn với các đối tượng java chuẩn. – james

+0

Không thực sự chắc chắn điểm là mặc dù. Thông tin nằm trong bộ nhớ _somewhere_.nếu kẻ tấn công có quyền truy cập vào bộ nhớ cục bộ, thì bạn bị kẹt khá nhiều. – james

Trả lời

0

Vì vậy, tôi đã đi đến kết luận, từ @jambjo và @james, rằng có thực sự không phải là bất cứ điều gì tôi có thể làm để ngăn ngừa các phím bị sao chép và trở thành không có tài khoản.

Chiến lược tốt nhất, với tư cách là nhà phát triển, sẽ thả thư viện mật mã xuống C (hoặc bất kỳ ngôn ngữ không được quản lý nào khác) và triển khai nội dung của bạn ở đó.

Tôi sẽ sẵn sàng chấp nhận câu trả lời từ người khác nếu họ có thể đưa ra giải pháp tốt hơn.

4

Java Cryptography Extension Reference Guide khuyên luôn sử dụng các mảng ký tự thay vì chuỗi cho mật khẩu để chúng có thể được xóa sau đó. Họ cũng cung cấp một ví dụ về mã số how you could implement it.

+0

Đây là một điểm rất tốt , nhưng tôi không chắc là đủ rồi. Vui lòng xem tôi cập nhật gần đây cho câu hỏi. –

+0

Ghi đè nội dung của một mảng là không đủ với các máy ảo Java mới hơn, vì mảng có thể được di chuyển xung quanh trong không gian bộ nhớ của quá trình, ví dụ: nếu heap được phân mảnh. – jarnbjo

1

Bạn đặt cược tốt nhất là sử dụng allocateDirect trong NIO. Trên một thực hiện lành mạnh, điều đó không nên được di chuyển về. Nhưng nó có thể sẽ đủ điều kiện cho phân trang ra đĩa (bạn có thể thăm dò ý kiến ​​nó, tôi đoán) và ngủ đông.

1

Vì vậy, những gì nếu dữ liệu trong bộ nhớ không bị ghi đè vào một thời điểm cụ thể? Nếu bạn phải lo lắng về kẻ tấn công đang đọc bộ nhớ của máy, thì đó là vấn đề, chứ không phải những gì anh ta có thể tìm thấy ở đó vào thời điểm nào.

Thực tế thực tế kịch bản tấn công là bạn lo lắng về nơi các phím còn lại ở đâu đó trong bộ nhớ của JVM có thể là một vấn đề nghiêm trọng? Nếu kẻ tấn công có thể nhìn vào bộ nhớ của JVM, anh ta cũng có thể nắm bắt các khóa đó trong khi bạn vẫn đang sử dụng chúng.

Và nếu bạn lo lắng về kẻ tấn công đang chạy với tư cách người dùng thông thường trên hệ thống, hãy giữ bộ nhớ bị loại bỏ bởi JVM: AFAIK, tất cả hệ điều hành hiện đại sẽ ghi đè bộ nhớ mới được phân bổ bằng số không.

+0

Đầu tiên, ý tưởng chỉ đơn giản là giảm thiểu rủi ro. Ít thời gian bạn có chìa khóa trong bộ nhớ, ít cơ hội nó sẽ phải được nhìn thấy bởi một kẻ tấn công. Tuy nhiên, có bạn là hoàn toàn chính xác. Vấn đề này tôi có là khá contrived. Yêu cầu FIPS 140-2 bắt nguồn từ yêu cầu phần cứng, trong đó _everyone_ được giả định có quyền truy cập vào phần cứng, vì vậy bạn muốn giảm cửa sổ tấn công. Đối với mô-đun phần mềm, điều này không có ý nghĩa nhiều. –

Các vấn đề liên quan