2013-06-17 40 views
11

Tôi đang tạo mô-đun Perl cung cấp giao diện OO cho API của bên thứ ba. Tôi muốn nắm bắt và lưu trữ mật khẩu của người dùng ở định dạng được mã hóa trước khi được truyền tới API của bên thứ ba. Module này chỉ được chạy trên các hệ thống dựa trên UNIX.Perl mã hóa mật khẩu STDIN

Tôi đã tạo tập lệnh sau thực hiện chức năng chụp - điều này có đúng theo nghĩa là nó chỉ lưu trữ biến mật khẩu ở định dạng được mã hóa không? Tôi lo ngại rằng mật khẩu có thể có sẵn trong bộ nhớ ở nơi khác (ví dụ: dưới $ _ mặc dù $ _ là undef).

NB. Tôi đang sử dụng STDIN thay vì @ARGV với giả định rằng hệ điều hành sẽ không đăng nhập mục nhập hoặc bao gồm mật khẩu trong tên quy trình. Tôi đang sử dụng một regex thay thế chứ không phải là chomp để đầu vào sẽ không phải được lưu trữ trong một biến không mã hóa tạm thời. Tôi cũng giả định rằng không thể hoàn toàn an toàn theo nghĩa là phần mềm chụp đầu vào vẫn có thể nắm bắt được đầu vào của người dùng.

Cảm ơn trước

use strict; 
use warnings; 
use Crypt::CBC; 
use 5.14.0; 

print 'Please enter your password: '; 
system('tty -echo'); 
my $key = Crypt::CBC->random_bytes(56); 
my $iv = Crypt::CBC->random_bytes(8); 
my $cipher = Crypt::CBC->new(-key => $key, 
          -cipher => 'Blowfish', 
          -salt => 1, 
          ); 
my $ciphertext = $cipher->encrypt(<STDIN> =~ s/\n$//r); 
system('tty echo'); 
+0

bạn có thể nên kiểm tra độ dài mật khẩu và '/ r' là viết tắt của cái gì? –

+1

@mpapec '/ r' là thay thế không phá hủy được giới thiệu trong perl 5.14 (xem perlop) - nó không sửa đổi chuỗi tại chỗ nhưng trả về một bản sao sửa đổi thay vào đó (tính năng rất tiện dụng). – Xaerxess

+2

Bạn đang cố gắng bảo vệ điều này từ đâu? Nếu ai đó có thể nhìn vào bộ nhớ quá trình của bạn để đọc mật khẩu được mã hóa, bạn phải giả định rằng họ cũng có thể đọc khóa và nguồn chương trình của bạn. Đọc mật khẩu từ stdin thay vì như một đối số dòng lệnh sẽ bảo vệ khỏi các trình duyệt thông thường, và có lẽ là tốt nhất bạn có thể mong đợi. –

Trả lời

6

Điều đó thật khó khăn.

Chạy mã mã hóa của bạn như một quá trình riêng biệt, mã con của mã chính, quá trình đọc từ STDIN và trả lại mật khẩu được mã hóa (và có thể là khóa). Theo cách đó, mã sử dụng mô đun của bạn sẽ không bao giờ giữ bản rõ trong bộ nhớ.

Chắc chắn, truy tìm và kiểm tra bộ nhớ (và hệ thống kiểm tra bộ nhớ sau khi chết quá trình) của trình trợ giúp trẻ em sẽ hiển thị bản rõ. Các kỹ thuật tương tự cũng sẽ tiết lộ khóa và bản mã được đọc từ một trình trợ giúp con. Tuy nhiên, nếu kịch bản mà bạn muốn bảo vệ là tình cờ giữ lại bản rõ trong quá trình của bạn - trong một đối tượng phức tạp hoặc một đóng cửa hoặc I-không-biết-một-temp-var-đã được phân bổ-đó - sau đó làm công việc trong một quá trình tận tụy, ngắn ngủi.

9
$ strace perl -E '<STDIN>' 
.... scroll, scroll, scroll .... 
read(0, 
... type, type, type .... 
"secret\n", 4096)    = 7 
exit_group(0)       = ? 

Tôi không nghĩ rằng bạn có thể ngăn chặn một người nào đó có quyền truy cập đầy đủ từ nhìn trộm bên trong các cuộc gọi hệ thống của bạn hoặc bộ nhớ.

3

Có vẻ như bạn đang triển khai Password Anti-pattern. Đó là một ý tưởng khủng khiếp - nó dạy người dùng bị lừa đảo. Làm ơn đừng làm thế. Bạn nên xem xét sử dụng OAuth để thay thế.

+0

Hãy khai sáng cho tôi cách tôi có thể sử dụng OAuth trên các ứng dụng dòng lệnh? Đặc biệt nếu API mà OP đang gói dự kiến ​​sẽ có mật khẩu * được mã hóa *? – amon

+0

Chắc chắn có thể (Tôi có các chương trình dòng lệnh Twitter sử dụng OAuth) nhưng thiết lập OAuth ban đầu có thể hơi phức tạp và cần trình duyệt. Xem https://github.com/davorg/localtwits/blob/master/build.pl để biết ví dụ. Nhưng ngay cả khi nó là không thể, đó không phải là một cái cớ để khuyến khích người dùng phá vỡ quy tắc bảo mật internet đầu tiên - Không bao giờ chia sẻ mật khẩu với bên thứ ba. –

+0

Cảm ơn - bằng cách sử dụng phương pháp này sẽ loại bỏ rất nhiều rủi ro bảo mật. Tôi nhận ra điều này không có trong bài đăng của tôi, tuy nhiên tôi cần tạo một mẫu XML được gửi qua https tới API của bên thứ ba.Nếu API của bên thứ ba không hỗ trợ OAutho một cách rõ ràng, tôi vẫn có thể sử dụng nó để giải quyết vấn đề này không? –

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