2012-12-11 31 views
6

Tôi phải mở đầu câu hỏi này bằng cách nói rằng tôi biết rằng mã hóa cứng một mật khẩu trong ứng dụng của khách hàng là thực hành không tốt, vì nhiều lý do. Có những câu hỏi khác liên quan đến vấn đề đó. Phạm vi của câu hỏi này là hẹp hơn và giả định rằng chứng thực xác thực CÓ phải nằm trên mã của ứng dụng khách cho một số lý do nằm ngoài tầm kiểm soát của bạn.Cách an toàn nhất để nhúng mật khẩu bên trong mã Java là gì?

Nếu một số cách tốt hơn so với các cách khác (ví dụ: JPasswordField lưu trữ mật khẩu trong mảng char thay vì chuỗi) và nếu bạn phải mã hóa nó trong ứng dụng Java, bạn có thể thực hiện các biện pháp nào để làm cho khó hơn để được tìm nạp?

Cập nhật:

Một ví dụ của ứng dụng chạy trên máy tính từ xa, nơi người dùng cuối có quyền quản trị. Thông tin đăng nhập được sử dụng để truy cập cơ sở dữ liệu trong cùng một mạng, vì vậy mật khẩu thực tế đã được xác định trước và phải được nhập thủ công trong mã thực tế.

+1

Bạn có nghĩ đến việc băm mật khẩu không? Có lẽ điều này sẽ làm việc cho trường hợp sử dụng của bạn? – Robin

+1

Bạn có thể vui lòng giải thích cách ứng dụng khách của bạn hoạt động không? Có bao nhiêu trường hợp nó chạy? Ai kiểm soát vòng đời của nó? Mật khẩu được sử dụng để làm gì? –

+1

Bạn có cần phải gửi mật khẩu ở một nơi khác, vì vậy bạn thực sự cần mật khẩu thực tế? Hoặc bạn có nhận được mật khẩu từ đâu đó (như người dùng) và chỉ cần kiểm tra xem nó có đúng không (và có thể sử dụng hàm băm cho điều đó) không? – hyde

Trả lời

5

.... nếu bạn phải mã hóa nó cứng trong ứng dụng Java , bạn có thể thực hiện các biện pháp nào để khó tìm nạp hơn?

Đối với một sự khởi đầu, tôi sẽ làm cho chết tiệt chắc chắn rằng người có trách nhiệm quản lý đối với việc ra quyết định tồi tệ này là hoàn toàn nhận thức được rằng đây là cơ bản và irredeemably không an toàn .

Sau đó, tôi có thể nghĩ ra một số thuật toán naff lắp ráp mật khẩu theo cách mơ hồ; ví dụ.bằng cách xây dựng hai mảng byte và XOR chúng lại với nhau ... và phân phối bytecode obfuscated. Điều tốt nhất bạn có thể hy vọng là làm cho mọi người khó có kỹ năng hạn chế để đảo ngược thiết kế mật khẩu từ mã của bạn.

(Mã hóa mật khẩu bằng thuật toán mạnh sẽ không giúp được gì nhiều, vì việc chọn thuật toán và khóa giải mã đều phải được nhúng vào mã của bạn. Thật vậy, bất kỳ chương trình nào bạn có thể mơ ước đều có thể bị đánh bại bằng cách sử dụng trình gỡ lỗi để đặt điểm ngắt tại điểm mà mật khẩu cần phải rõ ràng.)

1 ... và thậm chí Jon Skeet cũng không thể đảm bảo an toàn.


Nếu một số cách tốt hơn so với những người khác (ví dụ: JPasswordField lưu trữ các mật khẩu trong một mảng char thay vì một String) ...

Tôi chỉ muốn lưu ý bình thường lý do cho việc sử dụng mảng char để giữ mật khẩu trong JPasswordField và tương tự là để bảo vệ chống lại kẻ xấu đọc mật khẩu ra khỏi vùng lõi hoặc trao đổi tệp. Nó sẽ không thực sự giúp đỡ trong trường hợp này bởi vì chúng ta phải giả định rằng kẻ xấu có đủ quyền kiểm soát để đính kèm một trình gỡ rối vào JVM và nắm bắt các byte từ mảng char.

-1

bạn có thể băm mật khẩu và thậm chí mã hóa mật khẩu nếu muốn. hãy xem bài đăng này nó có thể hữu ích. Java - encrypt/decrypt user name and password from a configuration file

+3

Điều đó không giải quyết được vấn đề, bởi vì bạn sẽ ngay lập tức có một vấn đề mới giống như vấn đề ban đầu: làm thế nào bạn sẽ lưu trữ khóa giải mã một cách an toàn? – Jesper

1

Theo nguyên tắc chung, bạn không bao giờ nên lưu trữ mật khẩu (tất nhiên).

Nếu bạn cần có mật khẩu trong thời gian chạy, thực hành tốt nhất (ví dụ như được đưa vào sách Giao hàng liên tục của Jez Humble) là cung cấp mật khẩu khi triển khai/thời gian khởi động. Bằng cách này, mật khẩu có thể cư trú chỉ trong đầu của người dân thay vì trong một tập tin không an toàn ở đâu đó.

Tôi không biết liệu điều này có khả thi trong trường hợp của bạn hay không, nhưng bạn nên hướng tới điều đó.

1

Tôi đoán giải pháp ít lý tưởng nhất là, nếu bạn có thể có giao thức xác thực dựa trên thử thách với phần tử ngẫu nhiên trong đó.

Bằng cách đó không chỉ là mật khẩu, nó còn là mã sử dụng mật khẩu để tạo ra các câu trả lời đúng, cần được thiết kế ngược.

Sau đó, nó cũng có thể là xác thực hai chiều, đó là kết thúc của bạn có thể xác minh rằng phía bên kia cũng sử dụng cùng một giao thức/thuật toán và cũng có cùng một mật khẩu.

Và quan trọng nhất, khi đó mật khẩu sẽ không bao giờ được gửi qua mạng, do đó, nó không thể bị đánh hơi.

Diffie-Helman key exchange là một giao thức được sử dụng rộng rãi cho một điều như vậy, nhưng bạn luôn có thể triển khai thực hiện đơn giản của riêng mình, nếu bạn chỉ muốn tối tăm, không an toàn thực sự. Vâng, bảo mật thực sự rõ ràng là ngoài tầm với của bạn nếu mọi thứ có thể được biên dịch và đảo ngược thiết kế từ bytecode, nhưng dù sao ... :)

1

Rất không an toàn để lưu trữ dữ liệu nhạy cảm ở phía máy khách, đặc biệt đối với mật khẩu, vì các tệp .class có thể dễ dàng được giải mã. Bạn có bao giờ nghĩ đến việc có được một số công cụ mã hóa bất đối xứng có liên quan không? Giống như cặp khóa công khai/riêng tư hoặc một cái gì đó như thế?

0

Tôi thích câu trả lời của Stephen, nhưng tôi sẽ thêm ...

Bảo Mật Của Những mã nguồn là quan trọng quá. Bất kể bạn sử dụng phương pháp nào để làm xáo trộn mật khẩu, bất kỳ ai có quyền truy cập vào nguồn đều có thể dễ dàng đặt System.out.println(password) và nắm bắt mật khẩu được sử dụng hoặc chạy mã trong gỡ lỗi và tạm dừng mã để kiểm tra biến.

Ngay cả khi không biên dịch, bất kỳ ai có quyền truy cập vào jar đều có thể bắt đầu chương trình java ở chế độ gỡ lỗi và tạm dừng chương trình mà mật khẩu được sử dụng và kiểm tra biến, tầm thường với mã nguồn, nhưng vẫn có thể thực hiện được một số công cụ.

Bạn có thể xem chương trình nhận mật khẩu từ máy chủ bảo mật khi cần (thông qua cuộc gọi dịch vụ web hoặc bất kỳ thứ gì) và máy chủ đó sử dụng tường lửa để chỉ cho phép một số IP nhất định truy cập vào nó (nếu IP các máy khách được biết). Nó vẫn không an toàn, nhưng ít nhất nó là cái gì đó.

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