2011-03-29 28 views
20

Tôi có một bộ tạo mật khẩu:sẽ python SystemRandom/os.urandom luôn có đủ dữ liệu ngẫu nhiên cho crypto tốt

import random, string 

def gen_pass(): 
    foo = random.SystemRandom() 
    length = 64 
    chars = string.letters + string.digits 
    return ''.join(foo.choice(chars) for _ in xrange(length)) 

Theo các tài liệu, sử dụng SystemRandom os.urandom trong đó sử dụng/dev/urandom để ném ra ngẫu nhiên bit cryto. Trong Linux, bạn có thể nhận các bit ngẫu nhiên từ/dev/urandom hoặc/dev/random, cả hai đều sử dụng bất kỳ entropy nào mà hạt nhân có thể thực hiện được. Số lượng entropy có sẵn có thể được kiểm tra bằng đuôi/proc/sys/kernel/random/entropy_avail, điều này sẽ trả về một con số như: 129. Số entropy càng nhiều. Sự khác biệt giữa/dev/urandom và/dev/random là/dev/random sẽ chỉ nhổ ra bit nếu entropy_avail đủ cao (như ít nhất 60) và/dev/urandom sẽ luôn nhổ ra các bit. Các tài liệu nói rằng/dev/urandom là tốt cho mật mã và bạn chỉ phải sử dụng/dev/ngẫu nhiên cho ssl certs và tương tự.

Câu hỏi của tôi sẽ tốt cho việc tạo mật khẩu cấp mật mã mạnh mẽ? Nếu tôi gọi hàm này càng nhanh càng tốt, tôi sẽ ngừng nhận các bit cryto mạnh tại một số điểm vì hồ entropy bị cạn kiệt?

Câu hỏi cũng có thể là lý do tại sao/dev/urandom luôn luôn tạo ra các bit cryto mạnh không quan tâm đến entropy_avail? Có thể là/dev/urandom được thiết kế sao cho băng thông của nó bị giới hạn bởi số chu kỳ bạn có thể đoán sẽ tương quan với số lượng entropy, nhưng đây là suy đoán và tôi không thể tìm thấy câu trả lời.

Đây cũng là câu hỏi ngăn xếp đầu tiên của tôi, vì vậy hãy phê bình tôi. Tôi lo ngại rằng tôi đã đưa ra nhiều bối cảnh khi ai đó biết câu trả lời có thể biết nền.

Cảm ơn

cập nhật

tôi đã viết một số mã để xem xét các hồ bơi entropy trong khi /dev/urandom đã được đọc từ:

import subprocess 
import time 

from pygooglechart import Chart 
from pygooglechart import SimpleLineChart 
from pygooglechart import Axis 

def check_entropy(): 
    arg = ['cat', '/proc/sys/kernel/random/entropy_avail'] 
    ps = subprocess.Popen(arg,stdout=subprocess.PIPE) 
    return int(ps.communicate()[0]) 

def run(number_of_tests,resolution,entropy = []): 
    i = 0 
    while i < number_of_tests:   
     time.sleep(resolution) 
     entropy += [check_entropy()] 
     i += 1 
    graph(entropy,int(number_of_tests*resolution)) 

def graph(entropy,rng):  
    max_y = 200  
    chart = SimpleLineChart(600, 375, y_range=[0, max_y]) 
    chart.add_data(entropy) 
    chart.set_colours(['0000FF']) 
    left_axis = range(0, max_y + 1, 32) 
    left_axis[0] = 'entropy' 
    chart.set_axis_labels(Axis.LEFT, left_axis)  
    chart.set_axis_labels(Axis.BOTTOM,['time in second']+get_x_axis(rng)) 
    chart.download('line-stripes.png') 

def get_x_axis(rng): 
    global modnum   
    if len(filter(lambda x:x%modnum == 0,range(rng + 1)[1:])) > 10: 
     modnum += 1 
     return get_x_axis(rng) 
    return filter(lambda x:x%modnum == 0,range(rng + 1)[1:]) 

modnum = 1 
run(500,.1) 

Nếu chạy này và cũng chạy:

while 1 > 0: 
    gen_pass() 

Sau đó, tôi khá reliablly có được một đồ thị trông như thế này: enter image description here

Làm đồ thị khi chạy cat /dev/urandom trông smiler và cat /dev/random giọt off để không có gì và vẫn thấp rất nhanh chóng (điều này cũng chỉ đọc ra như một byte mỗi 3 giây hoặc lâu hơn)

cập nhật

Nếu tôi chạy thử nghiệm tương tự nhưng với sáu trường hợp của gen_pass(), tôi có được điều này: enter image description here

Vì vậy, có vẻ như một cái gì đó là làm cho nó là trường hợp mà tôi có đủ entropy. Tôi nên đo tốc độ tạo mật khẩu và đảm bảo rằng nó đang thực sự bị giới hạn, bởi vì nếu nó không phải là sau đó một cái gì đó fishy có thể đang xảy ra.

cập nhật

Tôi thấy điều này email chain

này nói rằng urandom sẽ ngừng kéo entropy khi hồ bơi chỉ có 128 bit trong đó. Điều này rất phù hợp với các kết quả trên và có nghĩa là trong các bài kiểm tra đó tôi thường xuyên tạo ra các mật khẩu rác.

Giả định của tôi trước đó là nếu entropy_avail đủ cao (nói trên 64 bit) thì đầu ra /dev/urnadom là tốt. Đây không phải là trường hợp có vẻ như là /dev/urandom được thiết kế để rời khỏi entropy thêm cho /dev/random trong trường hợp cần.

Bây giờ tôi cần phải tìm ra số lượng bit ngẫu nhiên thực mà một cuộc gọi SystemRandom cần.

+0

Đương nhiên nó có thể - bạn có thể vẽ một số lượng không xác định các thông tin từ/dev/urandom, và bạn không có số lượng entropy không xác định. –

+0

Giống như tôi đã nói ở trên, tôi nghĩ rằng bạn có thể thiết kế là để nó là không thể, nhưng tôi không có lý do gì tin điều này. Tôi cần nghiên cứu thêm. – Chris

+0

@Chris Làm cách nào? Entropy phải đến từ đâu đó - bạn không thể chỉ là ma thuật nó lên. Nếu bạn có thể, cuộc sống của chúng tôi sẽ dễ dàng hơn nhiều. –

Trả lời

7

Có sự khác biệt nhỏ giữa đầu ra của /dev/random/dev/urandom. Như đã được chỉ ra, /dev/urandom không chặn. Đó là bởi vì nó nhận được kết quả từ một trình tạo số giả ngẫu nhiên, được tạo thành từ các số ngẫu nhiên 'thực' trong /dev/random.

Đầu ra của /dev/urandom sẽ hầu như luôn luôn là ngẫu nhiên - đó là một PRNG chất lượng cao với một hạt giống ngẫu nhiên. Nếu bạn thực sự cần một nguồn dữ liệu ngẫu nhiên tốt hơn, bạn có thể xem xét việc tạo một hệ thống với trình tạo số ngẫu nhiên phần cứng - netbook của tôi có VIA C7, nó có thể tạo ra khá nhiều dữ liệu ngẫu nhiên đúng cách. kb/s trong số/dev/random, 545kb/s trong số/dev/urandom).

Là một sang một bên, nếu bạn đang tạo mật khẩu thì bạn có thể muốn xem pwgen - nó làm cho mật khẩu phát âm tốt đẹp cho bạn :).

+0

Nghi thức, tôi nghĩ rằng tôi đã chứng minh với bản thân mình rằng điều này sẽ làm việc tốt, nhưng để được an toàn phần cứng là con đường để đi. Bây giờ tôi chỉ cần tìm hiểu làm thế nào để móc geiger truy cập của tôi lên đến một cổng nối tiếp ... – Chris

+0

[Câu trả lời này là không chính xác] (http://security.stackexchange.com/questions/3936/is-a-rand-từ -dev-urandom-secure-for-a-login-key), cả hai 'random' và' urandom' đều lấy giá trị của chúng từ một PRNG. 'random' khối khi có quá ít entropy trong entropy pool, tuy nhiên entropy được lưu trữ và nạp lại khi bạn khởi động lại máy tính của bạn, vì vậy nó hầu như không bao giờ chạy thấp. Lần duy nhất 'urandom' có thể đưa ra" giá trị PRNG entropy thấp "là nếu bạn đã cài đặt máy mới và đọc ngay từ'/dev/urandom'. –

2

/dev/random/ sẽ chặn đọc nếu cần thêm entropy. /dev/urandom/ thì không. Vì vậy, có, nếu bạn sử dụng nó quá nhanh, bạn sẽ chạy thấp trên entropy. Có lẽ vẫn còn khá khó để đoán, tất nhiên, nhưng nếu bạn đang thực sự quan tâm bạn có thể đọc byte từ /dev/random/ thay thế. Lý tưởng nhất là, với vòng lặp đọc không chặn và chỉ báo tiến trình để bạn có thể di chuyển chuột xung quanh và tạo entropy nếu cần.

+0

'/ dev/random' thực sự dường như cung cấp cho bạn các bit trực tiếp từ entropy pool, và từ các thí nghiệm entropy bị cạn kiệt rất nhanh. Nếu có thể cho '/ dev/urandom' thất bại, tôi muốn biết thêm về nó như thế nào và nếu bạn có thể ngăn chặn nó. Nếu bạn chạy 'cat/dev/urandom' và sprap crap vào IO chuẩn và cũng kiểm tra entropy_avail theo định kỳ thì dường như không có vấn đề gì với entropy_avail. Nó làm cho tôi tự hỏi nếu hạt nhân đang sử dụng quá trình in '/ dev/urandom /' để tạo thêm entropy, tôi cũng tự hỏi liệu điều đó có chấp nhận được hay không. – Chris

+0

Hồi ức của tôi là họ lấy nó từ cùng một vị trí, nhưng 'ngẫu nhiên' theo dõi số lượng entropy có sẵn và chặn khi cần. Tôi cho rằng 'urandom' cũng cập nhật trạng thái entropy, vì ai đó có thể vẽ' ngẫu nhiên' bất cứ lúc nào. Bạn kiểm tra entropy_avail như thế nào? Dù sao, tôi muốn nói bằng cách sử dụng 'urandom' và chuyển nó qua một hàm băm an toàn sẽ đủ an toàn cho hầu hết mọi ứng dụng. –

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