2012-07-09 19 views
5

Tôi thực hiện một số dự án liên quan đến việc tự động gửi biểu mẫu và/hoặc truy xuất dữ liệu từ các trang web. Một số trang web này yêu cầu xác thực tên người dùng/mật khẩu. (Những trang web này không có API, vì vậy tôi đang dựa vào nạo màn hình.)Tôi có thể lập trình đăng nhập vào một trang web mà không lưu trữ mật khẩu trong văn bản thuần túy không?

Hầu hết các hướng dẫn Tôi đã nhìn thấy lưu trữ tên người dùng và mật khẩu trong mã nguồn giống như bất kỳ dữ liệu POST khác, ví dụ:

string username = "someUserName"; 
string password = "somePassword"; 
// submit POST data... 

Nhưng tôi biết lưu trữ mật khẩu ở dạng văn bản thuần túy thường không được chấp nhận. Có phương pháp thay thế nào tôi nên sử dụng không?

Trả lời

3

Cách phổ biến để lưu trữ mật khẩu là băm. Vì hầu hết các thuật toán cho mật khẩu băm là phá hoại, đó là chúng không thể được đảo ngược, điều này sẽ không làm việc cho bạn.

Một tùy chọn sẽ là sử dụng mã băm đảo ngược, chẳng hạn như mã hóa base64 mật khẩu, nhưng nó không thực sự an toàn hơn nhiều so với lưu trữ ở dạng văn bản thuần túy.

Giải pháp tốt nhất theo như tôi thấy, sẽ lưu trữ mật khẩu trong cơ sở dữ liệu. Nếu bạn thực sự lo lắng về việc ai đó nhận được tên người dùng và mật khẩu, bạn có thể mã hóa chúng trong DB với encryption functions hoặc bạn có thể sử dụng cơ sở dữ liệu SQLite mà bạn sẽ mã hóa trực tiếp trên đĩa.

Bằng cách này, mã của bạn và thông tin xác thực đăng nhập được tách riêng và bạn có thể chia sẻ mã của mình an toàn với người khác mà không phải lo lắng về bảo mật.

+0

Đó thực sự không phải là mã hóa. Nếu tập lệnh có thể nhận được mật khẩu văn bản thuần túy để bất kỳ ai cũng có quyền chạy nó. – pguardiario

+0

Bạn thực sự không thể tranh luận với mã hóa. Nếu nó được mã hóa, nó được mã hóa. Quan điểm của tôi là bạn có thể tách mật khẩu khỏi mã và lưu trữ chúng (mã hóa) trong cơ sở dữ liệu, chỉ làm cho chúng có sẵn thông qua mật khẩu chính. Làm thế nào OP quyết định xử lý mật khẩu chính là hoàn toàn tùy thuộc vào anh ta. Ví dụ. nhắc người dùng về mật khẩu chính khi khởi động sẽ ngừng truy cập trái phép vào mật khẩu. Tất nhiên, "bất cứ ai có quyền chạy nó" có thể, nhưng điều đó không ngụ ý truy cập vào mật khẩu. – jurgemaister

+0

Hmm, nhắc mật khẩu là tốt nhưng câu hỏi là làm thế nào để lưu trữ mật khẩu. Sử dụng một "mật khẩu chủ" thực sự chỉ cần thêm một mức độ phức tạp không cần thiết, và như xa như mã hóa đi ... Tôi không thấy những gì bảo vệ bạn đang hy vọng để có được từ rot13 hoặc bất kỳ chương trình đảo ngược bạn đang sử dụng. Nếu tôi có thể chạy tập lệnh, tôi có thể thấy mật khẩu. – pguardiario

0

Cách rất đơn giản để mã hóa và giải mã là extended tiny encription algorithm (XTEA). Tôi đang dán mã C++ từ wikipedia tại đây, nhưng hãy nhớ rằng bất cứ ai cũng có thể thay đổi nó ở đó.

#include <stdint.h> 

/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */ 

void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { 
    unsigned int i; 
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9; 
    for (i=0; i < num_rounds; i++) { 
     v0 += (((v1 << 4)^(v1 >> 5)) + v1)^(sum + key[sum & 3]); 
     sum += delta; 
     v1 += (((v0 << 4)^(v0 >> 5)) + v0)^(sum + key[(sum>>11) & 3]); 
    } 
    v[0]=v0; v[1]=v1; 
} 

void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) { 
    unsigned int i; 
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds; 
    for (i=0; i < num_rounds; i++) { 
     v1 -= (((v0 << 4)^(v0 >> 5)) + v0)^(sum + key[(sum>>11) & 3]); 
     sum -= delta; 
     v0 -= (((v1 << 4)^(v1 >> 5)) + v1)^(sum + key[sum & 3]); 
    } 
    v[0]=v0; v[1]=v1; 
} 
+0

Trong ý nghĩa gì? Thuật toán có dễ bị phá vỡ không? – sashoalm

+1

quan tâm: http://security.stackexchange.com/questions/3241/thoughts-on-tiny-encryption-algorithm-tea-anyone – Jacco

+0

Cảm ơn, tôi đã đọc liên kết. Tôi đã biết rằng TEA không an toàn lắm, nhưng tôi nghĩ rằng XTEA sửa lỗi đó. Tôi thậm chí không biết về XXTEA cho đến khi tôi đọc một trong những câu trả lời. Nhưng đây là loại moot anyway, OP đã lưu trữ mật khẩu trong một số cách trong máy tính của mình để cho điều này để làm việc, do đó, nó sẽ được vốn không an toàn không có vấn đề gì thuật toán ông sử dụng. – sashoalm

0

Bạn cần phải làm hai việc:
1. Sử dụng HTTPS cho trang đăng nhập (nếu cần thiết)
2. Sử dụng mật khẩu mã hóa ngay sau khi nhận được nó. Bộ mã hóa là một cái gì đó như thế này:

private static String passwordEncryption(String oldPass){ 
    String newPass = ""; 
    try { 
     MessageDigest messageDigest = MessageDigest.getInstance("MD5"); 
     messageDigest.update(oldPass.getBytes(), 0, oldPass.length()); 
     newPass = new BigInteger(1,messageDigest.digest()).toString(16); 
     if (newPass.length() < 32) { 
      newPass = "0" + newPass; 
     } 
     return newPass; 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return newPass; 

} 


Và sử dụng MD5() chức năng của MySql để so sánh mật khẩu nhận được với các lưu trữ một.

+0

việc sử dụng 'MD5()' ở phía MySQL là lời khuyên xấu: mật khẩu thô có thể/sẽ kết thúc trong các tệp nhật ký. – Jacco

0

Mẫu chúng tôi sử dụng là:

Trong bảng cơ sở dữ liệu của bạn, bạn có cột được mã hóa. Cột này chứa dữ liệu được mã hóa bằng một khóa bí mật dài (128 bit) toàn hệ thống, thường được lưu trữ trong tệp cấu hình). Dữ liệu trong cột được mã hóa này chứa khóa bí mật (ngẫu nhiên) riêng biệt được sử dụng cho mỗi dịch vụ của bên thứ ba. Với mật khẩu này, chúng tôi mã hóa các chi tiết xác thực liên quan đến dịch vụ bên thứ ba này.

Tại sao mã hóa kép này?

Bạn giảm số lượng mật khẩu ở dạng văn bản thuần túy thành một mật khẩu duy nhất (mật khẩu toàn hệ thống). Bởi vì điều này, quản lý khóa dễ dàng hơn. Chúng tôi tạo một khóa bí mật dài ngẫu nhiên cho mỗi dịch vụ của bên thứ ba để chúng tôi có thể giải mã có chọn lọc thông tin đăng nhập cho từng dịch vụ của bên thứ ba và chuyển chúng giữa các hệ thống nếu cần.Có một trong các khóa bí mật của chúng tôi được lưu trữ bên ngoài cơ sở dữ liệu cũng làm giảm nguy cơ liên quan đến cả các cuộc tấn công SQL injection (họ 'chỉ' lấy dữ liệu cơ sở dữ liệu) và với bản sao lưu (tệp cấu hình không được bao gồm trong dữ liệu sao lưu thông thường).

Điểm yếu rõ ràng là mật khẩu toàn hệ thống. Nó cần phải có trong bộ nhớ một nơi nào đó.

Tôi không có mật mã và tôi khá chắc chắn ở trên là tối ưu phụ. Tuy nhiên, nó hoạt động, có thể quản lý và an toàn hơn rất nhiều so với việc lưu trữ thông tin đăng nhập dịch vụ của bên thứ ba ở dạng văn bản thuần túy.

0

Không có cách nào để thực hiện. nó sẽ cần phải có sẵn cho kịch bản ở đâu đó dưới dạng văn bản thuần túy (hoặc "mã hóa đảo ngược").

Nhiều Apis (bao gồm cả Dịch vụ web của Amazon chẳng hạn) sẽ khuyên bạn nên đặt thông tin xác thực trong biến môi trường và điều này có thể an toàn như bạn mong đợi.

Đặt nó vào .bash_profile, séc kiểm tra kép của bạn và ít nhất bạn có thể chắc chắn nó sẽ không kết thúc trên github trong repo công cộng.

1

Tôi có một dự án cào mà cần giải quyết vấn đề này. Thiết lập của tôi bao gồm hai máy chủ riêng biệt. Đầu tiên là ứng dụng web giao diện người dùng cuối. thứ hai là một máy chủ nodejs xử lý việc cạo.

Tôi xử lý mã hóa bằng mã hóa cặp khóa mở. Tôi tạo một cặp khóa cho máy nodejs và cung cấp khóa công khai cho ứng dụng web giao diện người dùng. Khi người dùng đăng ký thông tin đăng nhập của bên thứ ba, các thông tin đăng nhập đó được mã hóa bằng khóa công cộng và được lưu trữ trong cơ sở dữ liệu.

Ứng dụng web thường xuyên chọn thông tin đăng nhập được mã hóa của người dùng và gửi chúng đến máy chủ nút nơi chúng được giải mã bằng khóa riêng và được sử dụng với bên thứ 3 để cạo.

Sau khi tìm kiếm nhanh, tôi đã tìm thấy this bài viết về cách sử dụng chuỗi mở khóa và mã hóa.

Tôi nhận thấy đây là một bài đăng rất cũ nhưng hy vọng nó sẽ giúp người tiếp theo tình cờ gặp vấn đề này.

+0

Xin chào! Thật vậy, điều đó đã giúp tôi! Nhưng làm cách nào để đảm bảo không ai có quyền truy cập vào khóa riêng của bạn? – nicolasdaudin

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