2010-03-25 29 views
12

Cách tốt nhất để tạo ra một mảng 32 byte an toàn mật mã bằng PHP, mà không phụ thuộc vào các thư viện hiếm khi được bao gồm trong các cài đặt PHP điển hình là gì?Tạo muối trong PHP

Sau một số googling tôi phát hiện ra rằng mt_rand không được coi là đủ an toàn, nhưng tôi chưa tìm thấy đề xuất thay thế. Một bài viết gợi ý đọc từ /dev/random nhưng không chỉ điều này sẽ không hoạt động trên các cửa sổ; nó cũng là rất chậm.

Tôi muốn có một sự cân bằng hợp lý giữa bảo mật và tốc độ (ví dụ, nó không nên dùng 20 giây để tạo ra 512 byte, như /dev/random thường làm)

+2

'/ dev/urandom' có thể được sử dụng để tạo nhanh hơn, nhưng vẫn không hoạt động trên các hệ thống Windows. – Amber

Trả lời

7

Lưu ý: mcrypt đã không được chấp nhận trong PHP 7.1. Skip to the up-to-date answer.

Bạn có thể xem tài liệu (và nhận xét) cho mcrypt_create_iv().

+1

mcrypt không được chấp nhận trong PHP 7.1. Bạn không nên viết mã đã không được chấp nhận. Vì vậy, nếu bạn đọc điều này vào năm 2016, không sử dụng câu trả lời này, thích câu trả lời của @Scott Arciszewski. – JesusTheHun

-9

Tôi nghĩ microtime() là đủ.

Thật lạ lùng, nhưng tôi vẫn nhận được sự phản đối cho câu trả lời này.

Mặc dù giải thích duy nhất tôi nhận được là microtime có thể dự đoán được.
Nghe có vẻ kỳ lạ với tôi vì muối luôn được giả định là được biết đến một cách công khai - vì vậy, hoàn toàn không có dự đoán nào.

+1

Không thực sự. Không chỉ rất dễ dự đoán (đó là thời điểm hiện tại), tôi cũng không thể nhận được 32 byte từ nó. – qster

+4

@qster bạn có thể sử dụng nó làm trình tạo số ngẫu nhiên. Và nhận được bất kỳ số lượng byte nào bạn muốn. Và nó không phải là thời điểm hiện tại, bạn đã làm sai lệch nó với thời gian(). Miligiây thay đổi khá nhanh. Và nó chỉ là muối, bạn không cần quá nhiều an ninh về muối. –

+0

@YourCommonSense Chạy 'echo microtime()' qua vòng lặp for (10 vòng là tốt) và xem bạn sai đến mức nào ... –

-3

uniqid() sẽ ổn cho mục đích này.

+1

Tôi sử dụng uniqid() với một số giá trị hạt giống có thể tính toán nhanh (như microtime được đề xuất). Đã không thực hiện một phân tích mật mã, nhưng dường như phù hợp với dự luật. – Boldewyn

0

Đọc từ /dev/urandom hoặc sử dụng openssl_random_pseudo_bytes().

7

Lưu ý: mcrypt không được dùng nữa trong PHP 7.1. Skip to the up-to-date answer.

Bạn có thể sử dụng hàm mycrypt_create_iv(), vì phiên bản PHP 5.3 cũng sử dụng nguồn ngẫu nhiên trên máy chủ Windows (không chỉ trên Unix). Trước khi sử dụng nó, bạn nên kiểm tra nếu hằng số MCRYPT_DEV_URANDOM được xác định.

mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); 

Không giống như ngẫu nhiên, urandom không chặn máy chủ, nếu không có đủ entropy. Vì muối mật khẩu nên là duy nhất (không nhất thiết là ngẫu nhiên), urandom có ​​vẻ là một lựa chọn tốt cho tôi.

+0

Xin lưu ý rằng đối số thứ hai là tùy chọn và giá trị 'MCRYPT_DEV_URANDOM' là giá trị mặc định - vì vậy nếu bạn không muốn thay đổi, bạn cũng có thể thực hiện' mcrypt_create_iv ($ length) '. Hơn thế nữa, tính năng này được thực hiện trong phần mở rộng 'mcrypt' có thể có hoặc không được cài đặt trên máy chủ của bạn. Cuối cùng, kết quả của hàm đó là một chuỗi nhị phân mà thường không phải là những gì bạn cần, vì bạn muốn lưu muối để tham khảo sau này. Tôi thường 'base64_encode' kết quả trước khi sử dụng nó như một muối. – Guss

+0

@Guss - Đây là những điểm tốt. Hơn nữa một trong những nhu cầu để kiểm tra, trong những gì mẫu muối dự kiến. Ví dụ, BCrypt sẽ không chấp nhận một muối nhị phân, nhưng một muối mã hóa base64 không hợp lệ. Đối với băm mật khẩu tốt nhất là sử dụng hàm built-in [password_hash()] (http://www.php.net/manual/en/function.password-hash.php), tạo ra một muối an toàn. – martinstoeckli

+0

Một lý do không sử dụng 'password_hash()' là tôi không triển khai mật khẩu. Tôi cần một muối để thực hiện một giao thức ủy quyền kiểu "api key" không trạng thái. – Guss

2

uniqueid không phù hợp để tạo chuỗi ngẫu nhiên vì nó cũng là microtime. Chu kỳ CPU thường ngắn hơn nhiều so với một dấu microtime, điều này có thể dẫn đến sự tồn tại có thể cho một biến nhất định trong vòng lặp. Đặt thông số thứ hai "entropy" thành true,

uniqid('', true) 

sẽ cung cấp tăng tính ngẫu nhiên.

Để có được một chuỗi ngẫu nhiên mà là cũng tương thích với hầu hết các nhân vật-bộ, người ta có thể áp dụng mã hóa base64 đến Mcrypt initilization chức năng vector mcrypt_create_iv:

$length = 16; 
base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM)) 
//> hlZuRJypdHFQPtI2oSFrgA== 
strlen(base64_encode(mcrypt_create_iv(ceil(0.75*$length), MCRYPT_DEV_URANDOM))) 
//> 16 

Giảm ký tự bảng chữ cái để 2^6bit tăng kích thước, được tính ở trên.

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