Tạo mật khẩu ngẫu nhiên; Tại sao không phải là di động?


21

Tôi muốn tạo một mật khẩu ngẫu nhiên và đang làm như vậy:

</dev/urandom tr -dc [:print:] | head -c 64

Trên máy tính xách tay của tôi chạy Ubuntu, điều này chỉ tạo ra các ký tự có thể in được, như dự định. Nhưng khi tôi vào máy chủ của trường tôi chạy Red Hat Enterprise Linux và chạy nó ở đó, tôi nhận được kết quả như thế nào 3!ri�b�GrӴ��1�H�<�oM����&�nMC[�Pb�|L%MP�����9��fL2q���IFmsd|l�K, điều này sẽ không làm được gì cả. Điều gì có thể xảy ra ở đây?

Câu trả lời:


34

Đó là vấn đề địa phươngtr của bạn .

Hiện tại, GNU tr chỉ hỗ trợ đầy đủ các ký tự một byte. Vì vậy, tại các địa phương sử dụng mã hóa đa bào, đầu ra có thể là lạ:

$ </dev/urandom LC_ALL=vi_VN.tcvn tr -dc '[:print:]' | head -c 64
`�pv���Z����c�ox"�O���%�YR��F�>��췔��ovȪ������^,<H ���>

Shell sẽ in chính xác các ký tự nhiều byte, nhưng GNU trsẽ loại bỏ các byte mà nó nghĩ là không thể in được.

Nếu bạn muốn nó ổn định, bạn phải đặt ngôn ngữ:

$ </dev/urandom LC_ALL=C tr -dc '[:print:]' | head -c 64
RSmuiFH+537z+iY4ySz`{Pv6mJg::RB;/-2^{QnKkImpGuMSq92D(6N8QF?Y9Co@

14
+1 vì điều này khiến tôi nhận ra (chỉ sử dụng shell trên Unix / Linux trong khoảng 30 năm), rằng chuyển hướng stdin / stdout / stderr không phải được định vị sau lệnh áp dụng.
Anthon 2/2/2015

Chỉ cần một nhận xét, nếu một số ngôn ngữ lạ được đặt, vỏ vẫn có thể in các ký tự chính xác, ngay cả khi chúng không phải là ascii? Ít nhất là một vỏ có thẩm quyền (tất nhiên không bao gồm xterm)?
orion

2
@orion: shell sẽ in các ký tự chính xác. Trong trường hợp này, đó là vấn đề tr. Nó loại bỏ các byte mà nó nghĩ là không thể in được, làm cho kết quả trở nên kỳ lạ.
cuonglm 2/2/2015

@orion Một luồng byte ngẫu nhiên thống nhất, nói chung, sẽ không phải là một luồng ngẫu nhiên thống nhất của các mã hóa ký tự UTF-8 được hình thành tốt .
zwol

Ngoài ra, trừ khi bạn có khoảng trắng nào trong mật khẩu của mình, bạn nên sử dụng :graph:thay vì :print::</dev/urandom LC_ALL=C tr -dc '[:graph:]' | head -c 64
edan

11

Thay vào đó hãy xem xét

$ dd if=/dev/urandom bs=48 count=1 status=none | base64
imW/X60Sk9TQzl+mdS5PL7sfMy9k/qFBWWkzZjbYJttREsYpzIguWr/uRIhyisR7

Điều này có hai lợi thế:

  • Bạn chỉ đọc 48 byte từ thiết bị ngẫu nhiên, không ~ 8KB; nếu các quy trình khác trên cùng một máy chủ cần số ngẫu nhiên, 8KB rút hết tất cả cùng một lúc có thể là một vấn đề nghiêm trọng. (Có, có thể cho rằng không ai nên sử dụng thiết bị ngẫu nhiên chặn , nhưng mọi người thì có .)

  • Đầu ra base64chứa hầu như không có ký tự có ý nghĩa đặc biệt. (Đối với không có gì cả, tack | tr +/ -_ở cuối dòng, và (như trong ví dụ) đảm bảo số lượng byte đầu vào để base64là bội số của 3.)

Mật khẩu được tạo theo cách này có chính xác 384 bit entropy, ít hơn một chút so với những gì bạn đang làm (log 2 96 64 ≈ 421.4), nhưng quá đủ cho hầu hết các mục đích (256 bit entropy vẫn an toàn khi "vẫn đoán khi Sun đốt cháy "lãnh thổ ngoại trừ các khóa RSA, AFAIK).


3

Những người khác đã chỉ ra rằng miền địa phương xác định những gì [:print:]có nghĩa là. Tuy nhiên, không phải tất cả các ký tự có thể in đều phù hợp với mật khẩu (thậm chí không có trong ascii). Bạn thực sự không muốn khoảng trắng, tab và # $% ^? trong mật khẩu của bạn - không chỉ khó nhớ, nó còn có khả năng gây nguy hiểm cho hệ thống xác thực cơ bản, có thể không thể nhập vào trường nhập, v.v. Trong trường hợp này, bạn chỉ nên chọn thủ công các ký tự "sane":

LC_ALL=C </dev/urandom tr -dc '[:alnum:]_' | head -c 64

hoặc đơn giản

</dev/urandom tr -dc 'A-Za-z0-9_' | head -c 64

Hoặc thậm chí tốt hơn, sử dụng base64như đề xuất trong câu trả lời khác.


Mật khẩu trong câu hỏi sẽ không bao giờ được nhập bởi con người (nếu đó là tôi đang sử dụng Diceware) và tôi khá chắc chắn rằng hệ thống cơ bản có thể xử lý các ký tự đặc biệt mà không gặp vấn đề gì. Dù sao cũng cảm ơn bạn.
Taymon 2/2/2015

4
Những gì bạn nói là hoàn toàn sai. Việc buộc người dùng chỉ sử dụng các chữ cái, chữ số và dấu gạch dưới ascii làm giảm đáng kể kích thước bảng chữ cái, giúp phá mật khẩu dễ dàng hơn nhiều cho những kẻ tấn công. Một hệ thống xác thực thậm chí không thể xử lý ?hoặc ^quá tệ để được thực hiện nghiêm túc.
Bakuriu

2
Nếu hệ thống xác thực hoặc trường nhập liệu của bạn bị nghẹt các ký hiệu ASCII thông thường ... thì bạn đang làm gì đó sai và không được tin cậy với thông tin cá nhân của tôi. Hoàn toàn không có lý do để không chấp nhận tất cả các loại ký tự (bao gồm cả khoảng trắng) trong mật khẩu của bạn.
nzifnab 2/2/2015

2
Có vẻ như đây không phải là trường hợp ở đây, nhưng khi nói đến đầu vào của con người, việc nhớ mật khẩu chữ và số dài có ý nghĩa duy nhất đối với chủ sở hữu sẽ dễ dàng hơn nhiều so với ký hiệu lộn xộn ngắn hơn. Ngoài ra còn có vấn đề nhập các ký tự này trên các bàn phím khác nhau (không phải ai cũng có ^ ở cấp độ đầu tiên và hầu hết mọi người thậm chí không biết backtick ở đâu hoặc là gì), các hộp nhập liệu gần như chắc chắn không thể xử lý ký tự tab và số lượng đáng ngạc nhiên của các biểu mẫu web vẫn còn dễ bị lỗi xác nhận, tiêm sql hoặc thậm chí độ nhạy trường hợp không chắc chắn.
orion

1
Chỉ cần một lưu ý: trong [:print:]lớp ngôn ngữ C không bao gồm các tab. Nó chỉ là [:alnum:]+ [:punct:]+ không gian (không gian duy nhất, không [:space:] ).
jimmij

2

Thế còn

tr -dc [:print:] < /dev/urandom | head -c 64 | strings

chuỗi nên in đầu ra của urandom theo định dạng có thể in


Điều này mang lại-bash: /dev/urandom: Permission denied
Anthon 2/2/2015

xin lỗi đã quên con mèo đầu đàn
Blindstealer

2

Tôi không biết có lý do nào khiến bạn sử dụng /dev/randomđể tạo mật khẩu không, nhưng tôi sẽ khuyên bạn nên sử dụng pwgen để giảm bớt nỗi đau của bạn.

$ pwgen -s 10 1

Trong đó 10 là độ dài của mật khẩu.

http://man.cx/pwgen


1
#Chars allowed in password (I don't like l,o,O, etc):
P="0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz"

#Or such:
#P="a-zA-Z0-9"

head -c 8 < /dev/urandom | tr '\000-\377' "$P$P$P$P$P"
echo

Phương pháp này IMHO thông minh hơn khi tiêu thụ dữ liệu từ / dev / urandom Chuỗi được dán dưới dạng $ P $ P $ P ... phải dài ít nhất 256 ký tự.

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.