2010-01-14 2 views
14

Tôi được yêu cầu viết API Web cho một ứng dụng (máy tính thực thi, không phải ứng dụng web) sẽ cho phép gửi email.
Người dùng nhấp vào nội dung nào đó, ứng dụng sẽ liên lạc với API tạo email và gửi đi.An ninh Web API

Tôi phải đảm bảo rằng không ai được phép truy cập vào API, vì vậy tôi cần thực hiện một số loại xác thực và tôi chưa có ý tưởng về cách thực hiện chính xác.

Sẽ có nhiều ứng dụng hơn truy cập API.

Suy nghĩ đầu tiên là - gửi tên người dùng và mật khẩu, nhưng điều này không giải quyết được vấn đề thực sự. Bởi vì nếu ai đó giải mã ứng dụng, họ sẽ có url yêu cầu và các biến bao gồm cả người dùng/mật khẩu hoặc chỉ đơn giản là nó có thể được ngửi.

vì vậy ... tôi có các tùy chọn nào?

Tôi khá chắc chắn kết nối an toàn (SSL) hiện không có sẵn cho tôi, nhưng vẫn còn, điều này sẽ không giúp tôi chống lại vấn đề giải mã, phải không?


EDIT

Tôi đã không nói rằng ban đầu, nhưng người dùng sẽ không được yêu cầu tên người dùng/mật khẩu. Đó là (các) ứng dụng sẽ phải được xác thực, chứ không phải người dùng (các) ứng dụng.

Trả lời

8

Tôi khuyên bạn nên xem OAuth. nó chắc chắn sẽ giúp bạn trong việc phân loại các vấn đề bảo mật bằng cách cho phép các công cụ truy cập vào API của bạn.

http://oauth.net

+0

Điều này giống như chính xác những gì tôi đang tìm kiếm. Cảm ơn! –

0

Bạn sẽ cần phải sử dụng SSL nếu bạn cần ngăn mọi người nhìn thấy mật khẩu thuần văn bản được gửi từ ứng dụng qua mạng tới API.

Đối với sự cố giải mã, bạn sẽ muốn lưu trữ mã băm của mật khẩu trong API chứ không phải mật khẩu ban đầu. Xem giải thích tại đây: http://phpsec.org/articles/2005/password-hashing.html.

3

Ai đó luôn có khả năng dịch ngược và tìm kiếm các biến. Một obfuscator có thể ẩn chúng tốt hơn một chút. Sniffing cũng dễ dàng mà không cần SSL trừ khi bạn sử dụng khóa riêng và khóa công khai để mã hóa phía máy khách yêu cầu dữ liệu và giải mã phía máy chủ (nhưng rõ ràng khóa này sẽ được lưu trữ trong ứng dụng khách).

Điều tốt nhất cần làm là cung cấp nhiều lớp bảo vệ như bạn nghĩ bạn sẽ cần, tạo kết nối an toàn và làm xáo trộn mã của bạn. Bạn có thể nhìn vào bài viết sau đây, trong đó thể hiện một kết nối an toàn mà không sử dụng SSL:

http://www.codeproject.com/KB/security/SecureStream.aspx

Như mattjames đề cập, bạn không bao giờ nên lưu trữ mật khẩu ở định dạng văn bản đơn giản. Khi người dùng nhập mật khẩu của họ vào ứng dụng, lưu trữ một băm mật khẩu. Cùng một băm nên được lưu trữ trên máy chủ. Bằng cách đó, nếu băm được nhìn thấy bởi một kẻ đánh chặn thì ít nhất họ cũng sẽ không nhìn thấy mật khẩu ban đầu của người dùng.

20

Việc phân phối phần mềm của bạn thực sự là mấu chốt của vấn đề.Việc băm tên người dùng và mật khẩu và lưu trữ chúng trong phần mềm không hữu ích hơn việc lưu trữ các giá trị chưa băm, vì một trong hai sẽ hoạt động để truy cập vào máy chủ API. Nếu bạn định triển khai tên người dùng và mật khẩu cho người dùng của mình, tôi nghĩ bạn có thể sử dụng tên đó như một điều khiển trước con trỏ tới API mà không lưu trữ các giá trị trong chính phần mềm đó. Hãy để tôi mô tả điều này trong hai phần.

Yêu cầu Chữ ký

Phương pháp phổ biến nhất được sử dụng để xác minh yêu cầu API là yêu cầu chữ ký. Về cơ bản, trước khi yêu cầu được gửi đến máy chủ API, các tham số trong yêu cầu được sắp xếp và một khóa duy nhất được thêm vào danh sách kết hợp. Toàn bộ lô sau đó được sử dụng để tạo ra một băm, được thêm vào yêu cầu. Ví dụ:

public static function generateRequestString(array $params, $secretKey) 
{ 
    $params['signature'] = self::generateSignature($params, $secretKey); 
    return http_build_query($params,'','&'); 
} 

public static function generateSignature($secretKey, array $params) 
{ 
    $reqString = $secretKey; 
    ksort($params); 
    foreach($params as $k => $v) 
    { 
     $reqString .= $k . $v; 
    } 
    return md5($reqString); 
} 

Bạn có thể tạo một chuỗi truy vấn yêu cầu API sử dụng mã ở trên chỉ đơn giản bằng cách gọi phương thức generateRequestString() với một mảng của tất cả các thông số bạn muốn gửi. Khóa bí mật là khóa được cung cấp duy nhất cho từng người dùng API. Nói chung, bạn chuyển id người dùng của mình tới máy chủ API cùng với chữ ký và máy chủ API sử dụng id của bạn để tìm khóa bí mật của bạn từ cơ sở dữ liệu cục bộ và xác minh yêu cầu theo cùng cách bạn đã tạo. Giả sử rằng khóa và id người dùng là chính xác, người dùng đó phải là người duy nhất có thể tạo chữ ký chính xác. Lưu ý rằng khóa không bao giờ được chuyển trong yêu cầu API.

Thật không may, điều này yêu cầu mọi người dùng phải có một khóa duy nhất, đây là vấn đề đối với ứng dụng dành cho máy tính để bàn của bạn. Dẫn tôi đến bước thứ hai.

Temporal Phím

Vì vậy, bạn không thể phân phối phím với các ứng dụng vì nó có thể được dịch ngược, và các phím sẽ thoát ra. Để phản tác dụng, bạn có thể tạo ra các khóa rất ngắn.

Giả sử bạn đã triển khai một phần của ứng dụng dành cho máy tính để bàn hỏi người dùng về tên người dùng và mật khẩu của họ, bạn có thể yêu cầu ứng dụng thực hiện yêu cầu xác thực cho máy chủ của bạn. Khi xác thực thành công, bạn có thể trả về khóa thời gian với phản hồi, ứng dụng dành cho máy tính để bàn sau đó có thể lưu trữ trong suốt thời gian của phiên được ủy quyền và sử dụng cho các yêu cầu API. Vì bạn đã đề cập rằng bạn không thể sử dụng SSL, xác thực ban đầu này là phần dễ bị tổn thương nhất và bạn phải sống với một số hạn chế.

Bài viết mà Andy E đề xuất là một cách tiếp cận tốt (tôi đã bình chọn nó). Về cơ bản nó là một cái bắt tay để thiết lập một khóa ngắn ngủi có thể được sử dụng để xác thực. Có thể sử dụng cùng một khóa cho băm chữ ký. Bạn cũng có thể mất cơ hội của bạn và chỉ cần gửi tên người dùng/mật khẩu không được mã hóa và nhận được một chìa khóa thời gian (nó sẽ chỉ xảy ra một lần), nhưng bạn phải biết rằng nó có thể được đánh hơi.

Tóm tắt

Nếu bạn có thể thiết lập một khóa phiên theo thời gian, bạn sẽ không cần phải lưu trữ bất cứ điều gì trong chương trình khách hàng có thể được dịch ngược. Một tên người dùng/mật khẩu được gửi một lần đến máy chủ của bạn là đủ để thiết lập điều đó. Khi bạn có khóa đó, bạn có thể sử dụng khóa đó để tạo yêu cầu trong ứng dụng dành cho máy tính để bàn và xác minh yêu cầu trên máy chủ API.

+6

+1 - Mặc dù tôi có nhận xét lại: 'Việc băm tên người dùng và mật khẩu và lưu trữ chúng trong phần mềm không hữu ích hơn việc lưu trữ các giá trị chưa băm, vì một trong hai sẽ hoạt động để truy cập máy chủ API'.Mặc dù điều này không liên quan đến người hỏi (như chỉnh sửa của anh ấy), nhưng mật khẩu người dùng băm là để nếu ai đó quản lý để nhận được băm, họ có thể ** chỉ ** truy cập vào API chứ không phải tài khoản giao diện người dùng hoặc ngay cả các dịch vụ khác trên web - vì nhiều người sử dụng cùng một mật khẩu cho các trang web khác nhau. Vì vậy nó vẫn khôn ngoan không lưu trữ mật khẩu dưới dạng văn bản thuần túy. –