Hiệu ứng thay đổi SECRET_KEY của Django


202

Tôi đã phạm sai lầm và cam kết dự án Django của tôi SECRET_KEYvào một kho lưu trữ công cộng.

Khóa này phải được giữ bí mật theo tài liệu https://docs.djangoproject.com/en/dev/ref/sinstall/#std:setting-SECRET_KEY

Dự án Django đang hoạt động và đã hoạt động được một thời gian với một số người dùng tích cực. Những ảnh hưởng nếu tôi thay đổi là SECRET_KEYgì? Bất kỳ người dùng hiện tại, cookie, phiên, vv .. sẽ bị ảnh hưởng? Rõ ràng, cái mới SECRET_KEYsẽ không còn được lưu trữ ở một địa điểm công cộng.

Câu trả lời:


199

Chỉnh sửa: Câu trả lời này dựa trên django 1.5

SECRET_KEY được sử dụng ở nhiều nơi khác nhau, tôi sẽ chỉ ra những gì bị ảnh hưởng bởi nó trước và sau đó cố gắng đi qua danh sách đó và đưa ra lời giải thích chính xác về tác động.

Danh sách những thứ sử dụng SECRET_KEYtrực tiếp hoặc gián tiếp:

Trong thực tế, rất nhiều vật phẩm được liệt kê ở đây sử dụng SECRET_KEYthông qua django.utils.crypt.get_random_string()đó sử dụng nó để gieo hạt giống ngẫu nhiên. Điều này sẽ không bị ảnh hưởng bởi sự thay đổi giá trị của SECRET_KEY.

Trải nghiệm người dùng bị ảnh hưởng trực tiếp bởi sự thay đổi giá trị là:

  • phiên, giải mã dữ liệu sẽ bị hỏng, đó là hợp lệ cho bất kỳ phụ trợ phiên nào (cookie, cơ sở dữ liệu, dựa trên tệp hoặc bộ đệm).
  • mã thông báo đặt lại mật khẩu đã được gửi sẽ không hoạt động, người dùng sẽ phải hỏi một mật khẩu mới.
  • mẫu nhận xét (nếu sử dụng django.contrib.comments) sẽ không xác thực nếu được yêu cầu trước khi thay đổi giá trị và được gửi sau khi thay đổi giá trị. Tôi nghĩ rằng điều này là rất nhỏ nhưng có thể gây nhầm lẫn cho người dùng.
  • tin nhắn (từ django.contrib.messages) sẽ không xác nhận phía máy chủ trong cùng điều kiện thời gian như đối với biểu mẫu nhận xét.

CẬP NHẬT : hiện đang làm việc trên django 1.9.5, một cái nhìn nhanh về nguồn cho tôi khá nhiều câu trả lời tương tự. Có thể làm một kiểm tra kỹ lưỡng sau này.


1
Tôi đang thay đổi SECRET_KEY trên máy chủ dev cục bộ của mình và điều đó không đăng xuất tôi, vì vậy có vẻ như ít nhất các phiên (bộ đệm) hoạt động chính xác sau khi thay đổi. Bạn có thể vui lòng giải thích thêm về ý của bạn data decode will breakvà có thể chỉ ra một số mã (trong django hoặc dự án ví dụ) sẽ phá vỡ? EDIT: vẫn đang sử dụng django 1.4 - có phải vậy không?
Kirill Zaitsev

@teferi Tôi không biết về 1.4, đó là vấn đề xem mã. Tôi đã chỉ vào tất cả các nguồn cho mỗi điểm, bạn có thể xem "bảo vệ dữ liệu phiên và tạo các khóa phiên ngẫu nhiên". Bình thường bạn vẫn đăng nhập nhưng bạn sẽ không thể đọc dữ liệu trong phiên như SECRET_KEYđược sử salted_hmacdụng để băm dữ liệu phiên.
sberder

Nếu nó được sử dụng cho muối băm mật khẩu, không có nghĩa là mật khẩu trong cơ sở dữ liệu phải được đặt lại?
Henning

7
@Henning Tôi không nghĩ vậy. Các mật khẩu được lưu trữ như <algorithm>$<iterations>$<salt>$<hash>trong auth_user, do đó muối ngẫu nhiên được lưu trữ cùng với mật khẩu trong từng trường hợp.
Denis Lagcher

2
Câu trả lời sẽ khác nhau đáng kể trong các phiên bản Django> 1.5? (ví dụ: hiện tại 1.9)
das-g

36

Vì câu hỏi này đã được hỏi, tài liệu Django đã thay đổi để bao gồm một câu trả lời.

Khóa bí mật được sử dụng cho:

  • Tất cả các phiên nếu bạn đang sử dụng bất kỳ phiên phụ trợ nào khác django.contrib.sessions.backends.cachehoặc đang sử dụng mặc định get_session_auth_hash().
  • Tất cả các tin nhắn nếu bạn đang sử dụng CookieStoragehoặc FallbackStorage.
  • Tất cả các PasswordResetViewmã thông báo.
  • Bất kỳ việc sử dụng ký mã hóa, trừ khi một khóa khác được cung cấp.

Nếu bạn xoay khóa bí mật của mình, tất cả những điều trên sẽ bị vô hiệu. Khóa bí mật không được sử dụng cho mật khẩu của người dùng và xoay khóa sẽ không ảnh hưởng đến họ.

Tôi không rõ chính xác tôi nên xoay khóa bí mật như thế nào. Tôi tìm thấy một cuộc thảo luận về cách Django tạo ra một chìa khóa cho một dự án mới , cũng như một Gist thảo luận về các lựa chọn khác . Cuối cùng tôi quyết định chỉ cần Django tạo một dự án mới, sao chép khóa bí mật mới vào dự án cũ của tôi và sau đó xóa dự án mới .

cd ~/junk # Go to some safe directory to create a new project.
django-admin startproject django_scratch
grep SECRET_KEY django_scratch/django_scratch/settings.py # copy to old project
rm -R django_scratch

Cập nhật

Có vẻ như Django đã thêm get_random_secret_key()chức năng trong phiên bản 1.10. Bạn có thể sử dụng nó để tạo một khóa bí mật mới.

$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
s!)5@5s79sp=92a+!f4v!1g0d0+64ln3d$xm1f_7=749ht&-zi
$ ./manage.py shell -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"
_)+%kymd=f^8o_fea1*yro7atz3w+5(t2/lm2cz70*e$2mn\g3
$

4
Có phải thế hệ khóa bí mật dựa vào khóa bí mật?
kdazzle

4
Không, @kdazzle, nếu bạn nhìn vào mã nguồnstartproject , bạn có thể thấy rằng nó chỉ tạo ra một chuỗi ngẫu nhiên bằng cách sử dụng cryptomô-đun.
Don Kirkby

12
Heh, xin lỗi, @DonKirkby, dở khóc dở cười
kdazzle 7/11/2015

16

Theo trang này https://docs.djangoproject.com/en/dev/topics/signing/ , SECRET_KEY chủ yếu được sử dụng cho các công cụ tạm thời - ví dụ, ký dữ liệu được gửi qua dây để bạn có thể phát hiện giả mạo. Có vẻ như những điều mà COULD phá vỡ là:

  • Các cookie đã ký, ví dụ: "ghi nhớ xác thực của tôi trên máy tính này". Trong trường hợp này, cookie sẽ bị vô hiệu, chữ ký sẽ không được xác minh và người dùng sẽ phải xác thực lại.
  • Đối với bất kỳ người dùng nào đã yêu cầu liên kết để đặt lại mật khẩu hoặc tải xuống tệp tùy chỉnh, những liên kết đó sẽ không còn hiệu lực. Người dùng chỉ cần yêu cầu lại các liên kết đó.

Một người có kinh nghiệm Django gần đây và / hoặc nổi bật hơn tôi có thể kêu vang, nhưng tôi nghi ngờ rằng trừ khi bạn rõ ràng đang làm gì đó với API ký, điều này chỉ tạo ra sự bất tiện nhẹ cho người dùng của bạn.


6
Vậy thì tại sao không tạo một khóa mới trên mỗi máy chủ khởi động lại?
osa

4
Nó có thể gây ra sự cố nếu bạn đang chạy cùng một máy chủ bằng nhiều quy trình.
dbn

1
@osa bạn có muốn đăng xuất TẤT CẢ người dùng của mình mỗi lần bạn đẩy mã / khởi động lại máy chủ của mình không?
EralpB

6

Chuỗi SECRET_KEY chủ yếu được sử dụng để mã hóa và / hoặc băm dữ liệu cookie. Rất nhiều khung công tác (bao gồm Django) đến với điều này vì cookie phiên mặc định có nhược điểm riêng.

Hãy tưởng tượng rằng bạn có biểu mẫu trong django để chỉnh sửa các bài viết với một trường ẩn. Trong trường ẩn này được lưu trữ ID của bài viết bạn đã chỉnh sửa. Và nếu bạn muốn chắc chắn rằng không ai có thể gửi cho bạn bất kỳ id bài viết nào khác, bạn sẽ thêm một trường ẩn bổ sung với id băm. Vì vậy, nếu ai đó sẽ thay đổi ID, bạn sẽ biết điều đó bởi vì hàm băm sẽ không giống nhau.

Tất nhiên đây là một ví dụ tầm thường nhưng đây là cách sử dụng SECRET_KEY.

Django được sử dụng ví dụ cho {% csrf_token%} và một vài thứ khác. Nó thực sự không nên có bất kỳ tác động nào đến ứng dụng của bạn nếu bạn sẽ thay đổi nó, dựa trên câu hỏi của bạn và rằng bạn không sử dụng nó.

Điều duy nhất là có thể các giá trị phiên sẽ bị loại bỏ. Vì vậy, ví dụ người dùng sẽ phải đăng nhập lại vào quản trị viên, vì django sẽ không thể giải mã phiên bằng khóa khác.


1

Tôi đã phạm sai lầm tương tự. Mật khẩu mặc định là 50, vì vậy tôi đã sử dụng powershell để tạo một chuỗi ngẫu nhiên dài 50 và thay thế SECRET_KEY cũ bằng nó. Tôi đã đăng nhập và sau khi thay thế SECRET_KEY phiên trước đó của tôi đã bị vô hiệu.

Với Powershell ( nguồn ):

# Load the .net System.Web namespace which has the GeneratePassword function
[Reflection.Assembly]::LoadWithPartialName("System.Web")

#  GeneratePassword(int length, int numberOfNonAlphanumericCharacters)
[System.Web.Security.Membership]::GeneratePassword(50,5)

Với Bash ( nguồn ):

# tr includes ABCabc123 and the characters from OWASP's "Password special characters list"
cat /dev/urandom | tr -dc 'A-Za-z0-9!"#$%&\''()*+,-./:;<=>?@[\]^_`{|}~' | head -c 100 ; echo

Tại thời điểm này tôi đã nghĩ tại sao không thử một phím lớn hơn, vì vậy tôi đã thử nó với một phím dài 100 và 1000. Cả hai đều làm việc. Nếu tôi hiểu mã nguồn , đối tượng được trả về bởi hàm người ký là hàm băm hmac trong base64. RFC 2104 có điều này để nói về độ dài cần thiết của khóa bí mật HMAC.

Các ứng dụng sử dụng khóa dài hơn byte B trước tiên sẽ băm khóa bằng H và sau đó sử dụng chuỗi byte L kết quả làm khóa thực tế cho HMAC.

Khóa cho HMAC có thể có độ dài bất kỳ (các khóa dài hơn byte B được băm đầu tiên bằng H). Tuy nhiên, ít hơn L byte được khuyến khích mạnh mẽ vì nó sẽ làm giảm cường độ bảo mật của chức năng. Các khóa dài hơn L byte được chấp nhận nhưng độ dài thêm sẽ không làm tăng đáng kể cường độ chức năng. (Khóa dài hơn có thể được khuyến khích nếu tính ngẫu nhiên của khóa được coi là yếu.)

Để dịch sang tiếng nói bình thường, kích thước của khóa bí mật cần phải có cùng kích thước với đầu ra. Chìa khóa cũng cần phải được tính bằng bit. Mỗi chữ số trong base64 đại diện cho 6 bit. Vì vậy, nếu bạn có mật khẩu 50 ký tự, bạn sẽ có khóa bí mật 50 x 6 = 300 bit. Nếu bạn đang sử dụng SHA256, thì bạn sẽ cần một khóa 256 bit ( sha256 sử dụng 256 bit theo định nghĩa ). Vì vậy, mật khẩu dài 50 sẽ hoạt động trừ khi bạn có kế hoạch sử dụng thuật toán băm lớn hơn SHA256.

Nhưng vì bất kỳ bit bổ sung nào trong khóa đang được băm, kích thước của nó sẽ không làm giảm đáng kể hiệu năng. Nhưng nó sẽ đảm bảo cho bạn rằng bạn có đủ bit cho các hàm băm lớn hơn. SHA-512 sẽ được bao phủ bởi 100 SECRET_KEY dài ( 50 x 6 = 600 bit> 512 bit ).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.