it-swarm-vi.com

Liệu bí mật API có được lưu trữ trong văn bản thuần túy hoặc có thể giải mã được không?

Không API keys được coi là tên người dùng và API secrets coi mật khẩu? Tại sao các máy chủ API như Amazon Web Services cho phép bạn xem bí mật API của mình bằng văn bản thuần túy? Nó khiến tôi nghĩ rằng họ lưu trữ nó trong văn bản đơn giản hoặc ít nhất là ở định dạng có thể giải mã.

Sẽ không tốt hơn nếu các bí mật API được coi là mật khẩu mà bạn nên nhập để tạo sau đó được băm trong cơ sở dữ liệu thay vì được trao cho bạn bằng văn bản thuần túy? Nếu vì lý do nào đó, cơ sở dữ liệu bí mật API của họ bị xâm phạm, nó sẽ dễ dàng mở các cửa xả lũ cho nhiều ứng dụng đang sử dụng API của họ. Tuy nhiên, nếu nó được băm theo cách không thể giải mã thì tất cả không dễ bị mất.

36
IMB

Không. Các khóa API cần được lưu trữ trong văn bản rõ ràng.

Chúng không phải là mật khẩu: chúng là khóa mật mã. Các khóa này được sử dụng cho những việc như xác thực các yêu cầu (sử dụng SHA1-HMAC). Máy chủ cần biết khóa mật mã để áp dụng các thuật toán mã hóa.

Do đó, khóa API cần được lưu trữ trong văn bản rõ ràng trên máy chủ. Nếu máy chủ chỉ lưu trữ một hàm băm của khóa API, nó không thể xác minh tính xác thực của tin nhắn từ máy khách hoặc xác thực tin nhắn được gửi đến máy khách.

17
D.W.

Băm là không lưu trữ; nó phá hủy dữ liệu không thể đảo ngược. Chúng ta có thể thoát khỏi việc gọi băm mật khẩu là "lưu trữ mật khẩu" bởi vì khi chúng ta thực sự cần mật khẩu, chúng ta có một toán tử người tiện dụng để nhập nó. Thật vậy, khi chúng ta băm mật khẩu, chúng ta không lưu trữ mật khẩu, mà chỉ là một mã thông báo đủ để xác minh mật khẩu đã nhập.

Khóa API phải được lưu trữ theo cách mà nó có thể được sử dụng lại theo cách không giám sát . Máy chủ phải thực sự lưu trữ nó, thay vì chỉ nhớ một bóng ma của nó, bởi vì nó cần khóa chính hãng để truy cập API.

13
Tom Leek

Mặc dù sẽ an toàn hơn khi băm các mã thông báo API, nhưng nó lại gây ra một vấn đề về khả năng sử dụng: các mã thông báo dài và ngẫu nhiên và sẽ chỉ được thông báo cho người dùng một lần trước khi băm. Điều này làm cho một chút khó khăn để bảo mật chúng bằng một hàm băm.

Đề xuất của tôi cho một kịch bản an toàn sẽ là như sau:

  1. Tạo một giá trị salt ngẫu nhiên và lưu trữ nó trong cơ sở dữ liệu. Muối này không được bằng muối mật khẩu của người dùng.
  2. Lấy mật khẩu văn bản gốc của người dùng và tính KDF(password, salt), trong đó KDF là một hàm dẫn xuất khóa như bcrypt. Gọi giá trị kết quả k.
  3. Tạo khóa API.
  4. Mã hóa giá trị khóa API bằng AES, sử dụng k làm khóa và lưu trữ bản mã trong cơ sở dữ liệu.
  5. Hủy khóa API bản rõ và k.

Khi người dùng đăng nhập, webapp sẽ biết mật khẩu của họ và sử dụng nó để tính k, sau đó được sử dụng để giải mã khóa API và hiển thị cho họ.

Khi người dùng muốn sử dụng API, họ phải gửi k cũng như khóa API văn bản gốc, qua SSL. Sau đó, ứng dụng web có thể giải mã giá trị khóa API được lưu trữ bằng cách sử dụng k và so sánh nó với khóa API đã cho. Nếu chúng khớp, nó hợp lệ. Điều này cho phép sử dụng khóa API mà không cần ứng dụng lưu trữ mật khẩu của người dùng.

Nếu kẻ tấn công vi phạm cơ sở dữ liệu, họ phải bẻ khóa mật khẩu của người dùng để tính k.

9
Polynomial

Dường như có một chút nhầm lẫn ở đây và những nơi khác , vì vậy tôi đang thêm câu trả lời này với hy vọng rằng nó sẽ làm rõ tình huống cho những người dùng khác.

Có hai loại bí mật API có thể được sử dụng.

Trường hợp sử dụng mà hầu hết các câu trả lời trên trang này đang thảo luận là một khóa bí mật được sử dụng để ký và xác minh tin nhắn bằng thuật toán như HMAC. Trong trường hợp này, cả máy khách và API đều cần giá trị thực của khóa để tạo chữ ký của thông báo. Sau đó, máy chủ sẽ so sánh chữ ký mà nó đã tạo với chữ ký mà khách hàng đã gửi và có thể xác minh tin nhắn. Như đã đề cập ở trên, nếu khóa gốc không thể sao chép trên máy chủ thì điều này không thể hoạt động. Sau khi ban đầu chia sẻ khóa với máy khách (qua kênh được mã hóa), khóa không cần phải được truyền giữa máy khách và máy chủ nữa.

Bí mật ứng dụng API phổ biến khác chỉ là thông tin xác thực bí mật (như bạn có thể thấy trong yêu cầu mã thông báo truy cập OAuth2 điển hình). Thông tin này được truyền theo từng yêu cầu và do đó chỉ nên được truyền qua kênh được mã hóa (chẳng hạn như HTTPS). Trong trường hợp này, máy chủ chỉ cần giữ lại đủ thông tin để xác minh rằng giá trị bí mật do khách hàng cung cấp là chính xác, vì vậy bí mật có thể và nên được băm. Trong trường hợp này, bí mật có hiệu quả như một mật khẩu, và do đó nên thực hiện các biện pháp phòng ngừa tương tự.

Tuyên bố miễn trừ trách nhiệm: Tôi không phải là nhà nghiên cứu bảo mật và bạn hoàn toàn nên nghiên cứu thêm về vấn đề này và bất kỳ chủ đề nào trước khi mù quáng làm theo bất kỳ lời khuyên nào về StackExchange này.

tl; dr Điều quan trọng nhất là các API khác nhau có thể sử dụng bí mật theo những cách khác nhau. Điều quan trọng là phải hiểu cách API của bạn sử dụng bí mật máy khách để đánh giá các thực tiễn tốt nhất để lưu trữ API.

8
Nick Sloan

Đặt hai xu của riêng tôi vì một vấn đề chưa được đề cập. Cụ thể, tôi đồng ý với những gì @NickSloan đã nói, nhưng với một lời cảnh báo nữa.

Có một sự khác biệt quan trọng hơn giữa khóa API và mật khẩu. Khóa API là duy nhất cho trang web của bạn. Phần làm cho bảo mật mật khẩu rất quan trọng là chia sẻ mật khẩu. Nếu ai đó nắm giữ mật khẩu mà người dùng đã lưu trên trang web của bạn, thì đó không chỉ là trang web của bạn bị xâm phạm: đó là mọi trang web khác mà người dùng đã sử dụng mật khẩu đó (và email/tên người dùng). Nhiều người sử dụng lại mật khẩu trên các trang web quan trọng: ngân hàng, phương tiện truyền thông xã hội, email, v.v. Chúng tôi không thể buộc người dùng thực hiện bảo mật tốt hơn, vì vậy chúng tôi phải thừa nhận điều tồi tệ nhất và thực hiện các bước bổ sung để họ bảo vệ quyền riêng tư của họ.

Khóa API là một kịch bản hoàn toàn khác vì nó là duy nhất cho trang web của bạn. Kết quả là, nếu nó bị đánh cắp, kẻ tấn công sẽ có quyền truy cập vào trang web của bạn, nhưng không kiếm được gì mà chúng có thể tận dụng để chống lại ngân hàng/email/v.v. Điều này có nghĩa là mức độ rủi ro cho các khóa API thực sự thấp hơn mức mật khẩu. Chúng không hoàn toàn trong cùng một công viên bóng: Các khóa API gần giống với định danh phiên hơn là mật khẩu.

Hiểu rằng đây là những thứ giống với định danh phiên hơn là mật khẩu cung cấp một số hiểu biết thực tế về cách bảo vệ đúng các khóa đó. Lưu ý rằng cuộc thảo luận sau có thể áp dụng cho Khóa API cho những thứ như OAuth thông tin xác thực và không phải thông tin mã hóa (như thảo luận của @NickSloan trong câu trả lời của anh ấy).

Các mối đe dọa lớn nhất đối với mật khẩu là các cuộc tấn công lừa đảo và cơ sở dữ liệu bị tấn công, đó là lý do tại sao chúng tôi lưu trữ chúng được băm trong cơ sở dữ liệu của chúng tôi. Các mối đe dọa lớn nhất đối với các khóa API cũng giống như đối với các khóa phiên: điểm yếu trong các ứng dụng ngoại vi như lỗ hổng XSS, MIM và tương tự. Điều quan trọng cần lưu ý là ứng dụng front-end cần mật khẩu ở dạng không được mã hóa, do đó, việc băm khóa API không thực sự mang lại cho bạn bất cứ điều gì khi người có khả năng bị đánh cắp cần nó ở dạng văn bản đơn giản.

Thay vào đó, bạn bảo vệ số nhận dạng phiên (hoặc OAuth hoặc khóa API dành riêng cho khách hàng) chủ yếu bằng cách theo dõi khách hàng. Nếu số nhận dạng phiên bị đánh cắp qua XSS hoặc các phương tiện khác từ máy khách , một kết quả điển hình là cho kẻ nhận dạng đó được kẻ tấn công sử dụng trên thiết bị mới. Điều đó có nghĩa là bất ngờ bạn sẽ thấy một khóa cũ xuất hiện với tác nhân người dùng mới. Thay đổi như vậy rất dễ phát hiện và sửa chữa: ngay lập tức làm mất hiệu lực tất cả các khóa API. Đặc biệt trong trường hợp OAuth yêu cầu, điều này rất không gây đau đớn cho người dùng: họ chỉ cần đăng nhập lại và ngay lập tức nhận được một khóa mới, trong khi ai đó chỉ lấy trộm khóa (và không có mật khẩu) trở lại bảng vẽ.

Đây là một biện pháp phòng thủ đủ phổ biến mà một hacker thông minh hơn cũng sẽ cố gắng ghi lại tác nhân người dùng được liên kết với khóa bị đánh cắp và sử dụng nó trong tất cả các yêu cầu trong tương lai, nhưng bạn vẫn có thể dễ dàng thấy điều gì đó đáng nghi xảy ra khi cùng một người dùng yêu cầu từ nhiều địa chỉ IP. Giống như mọi thứ khác trên thế giới, đây có thể là một chút trò chơi mèo vờn chuột, nhưng có một số bước đi quan trọng:

  1. Mã khóa API/Mã thông báo OAuth/ID phiên thực sự chỉ là một cách để ghi nhớ người dùng trên một thiết bị cụ thể, vì vậy họ không phải đặt mật khẩu của mình trên mỗi trang. Do đó, khi nghi ngờ, bạn có thể giết tất cả các khóa được ủy quyền và buộc người dùng đăng nhập lại.
  2. Trong cả ba trường hợp, do mất Khóa/Mã thông báo/ID dẫn đến tài khoản bị xâm phạm, điều quan trọng là phải có một số bảo mật tích cực xung quanh những điều này và phát hiện/phản hồi nếu có bất kỳ điều gì đáng nghi xảy ra. Nếu bạn đã từng nhận được thông báo từ facebook/google/etc về việc ai đó đang cố đăng nhập vào tài khoản của bạn từ Mexico, thì đó là vì một nhân viên bảo mật ở đâu đó đang thực hiện đúng công việc của họ.
  3. Các vectơ tấn công chính cho Khóa/Mã thông báo/Id khác với mật khẩu. Bạn vẫn có thể muốn băm chúng trong cơ sở dữ liệu của mình (một lần nữa, chúng tôi không nói về thông tin mã hóa cần phải ở dạng văn bản thuần túy), nhưng bạn không thể băm chúng trong cơ sở dữ liệu của mình và tự bảo mật. Bạn cần chắc chắn và bảo vệ chúng trước một loạt các vectơ tấn công mới. Nếu bạn nghĩ chúng chỉ là mật khẩu, bạn sẽ bỏ lỡ một số phần quan trọng của bức tranh lớn.
5
Conor Mancone

Một trong những lý do chính khiến mật khẩu được băm trước khi lưu trữ chúng, là để bảo vệ chống lại kẻ tấn công có được quyền truy cập chỉ đọc vào cơ sở dữ liệu . Theo cách này, nếu kẻ tấn công nắm giữ danh sách thông tin đăng nhập, họ vẫn không thể sử dụng chúng trực tiếp vì mật khẩu được băm/muối.

Và đây không chỉ là vấn đề lý thuyết mà chúng tôi đang cố gắng giải quyết ở đây, những kiểu tấn công này thực sự xảy ra ( bao gồm cả những người chơi chính trong ngành công nghiệp ) và băm thích hợp sẽ giúp giảm thiểu tác động của một cuộc tấn công.

Nếu bạn cài đặt người dùng xác thực bằng cách sử dụng bí mật API thì bí mật API đã thực sự trở thành mật khẩu , do đó, từ quan điểm bảo mật, họ nên có cùng một cơ chế bảo vệ như mật khẩu thông thường có.

Bản thân Amazon bây giờ không cho phép truy xuất bí mật API . Nếu bạn quên nó, bạn phải yêu cầu một cái mới.

2
Pedro Rodrigues

Không, nó không ổn đối với một số loại dịch vụ.

Thực hiện

1. Khi người dùng kết nối với mật khẩu đăng nhập, hãy tạo một khóa được lấy từ mật khẩu của anh ấy/cô ấy để mã hóa dữ liệu cho người dùng này và giữ nó trong một phiên trên máy chủ.

Bằng cách đó, mỗi người dùng sẽ có một khóa duy nhất. Khóa dẫn xuất này không được đảo ngược, đây là điểm chính. Sử dụng hàm hash_mac hoặc phương pháp băm khác với muối và/hoặc khóa chính sẽ cho phép điều này.

2. Sử dụng khóa này để mã hóa API Secret được tạo bằng AES 256 với iv ngẫu nhiên cho mỗi người dùng.

Hoặc là

2.bis Sử dụng khóa này để tạo khóa mã hóa thực sự vào giây phút cuối cùng và mã hóa phương thức API bằng cách sử dụng tương tự như trong 2. để tránh mật khẩu trôi nổi trong bộ nhớ.

. Lưu trữ iv trong cơ sở dữ liệu cùng với id người dùng và id ứng dụng trong một bảng chuyên dụng

4. Lưu trữ Bí mật API được mã hóa trong cơ sở dữ liệu trong bảng thích hợp.

Cách sử dụng

Bây giờ khi người dùng kết nối với bảng điều khiển của mình, bạn có thể tạo lại khóa, tìm nạp iv, giải mã API Secret cho người dùng này và hiển thị nó dưới dạng văn bản rõ ràng. Bạn cũng hiển thị khóa và yêu cầu cả hai khi thực hiện Cuộc gọi API để bạn có thể xác minh Bí mật ứng dụng.

Nếu bạn muốn tránh hiển thị khóa và không phải yêu cầu nó trong lệnh gọi API, bạn cũng có thể xác thực bằng cách sử dụng phương thức tương tự như để đăng nhập. Có nghĩa là bạn có thể tạo một bảng khác để lưu trữ khóa/muối ngẫu nhiên cho mỗi ứng dụng khách và lưu trữ phiên bản hash_mac của API Secret. Do đó, chỉ có ID API và API Secret được yêu cầu để xác thực Yêu cầu API. nhưng đó là công việc nhiều hơn.

Lưu ý

Điều này thực tế giống như câu trả lời @Polynomial.

Bằng cách này, rất khó để ai đó hack máy chủ và cơ sở dữ liệu của bạn để đánh cắp thông tin đăng nhập của người dùng của bạn và thực hiện cuộc gọi api thay cho họ. Bây giờ bạn có thể đánh giá rằng nếu một yêu cầu đã được chấp nhận từ máy khách API thì đó là máy khách phù hợp hoặc đó là sự rò rỉ của chúng.

Nếu người dùng mất mật khẩu thì bạn sẽ tạo lại API Secret và Key mới từ mật khẩu mới của anh ta.

0
Nicolas Manzini