17

tôi đang tìm kiếm một thuật toán cho tập tin mã hóa/giải mã mà đáp ứng các yêu cầu sau:Ruby: mã hóa tập tin/giải mã với tư nhân/khóa công khai

  • Thuật toán phải đáng tin cậy
  • Thuật toán cần được nhanh chóng cho khá file lớn
  • chính tư nhân có thể được tạo ra bởi một số tham số (ví dụ, mật khẩu)
  • tạo private key phải phù hợp với khóa công khai (public key được tạo ra một lần duy nhất và được lưu trữ trong cơ sở dữ liệu)

Có bất kỳ triển khai thực hiện Ruby nào của các thuật toán được đề xuất không?

Trả lời

26

Lưu ý: Như đề cập trong phần bình luận, câu trả lời này không phù hợp với hệ thống thực tế. Thứ nhất, mã hóa tập tin không được thực hiện bằng phương pháp này (ví dụ: lib cung cấp AES). Thứ hai, câu trả lời này không giải quyết bất kỳ vấn đề nào rộng lớn hơn cũng sẽ ảnh hưởng đến cách bạn xây dựng giải pháp của mình.

Nguồn gốc cũng đi vào more details.

Ruby có thể sử dụng openssl để làm điều này:

#!/usr/bin/env ruby 

# ENCRYPT 

require 'openssl' 
require 'base64' 

public_key_file = 'public.pem'; 
string = 'Hello World!'; 

public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file)) 
encrypted_string = Base64.encode64(public_key.public_encrypt(string)) 

Và giải mã:

#!/usr/bin/env ruby 

# DECRYPT 

require 'openssl' 
require 'base64' 

private_key_file = 'private.pem'; 
password = 'boost facile' 

encrypted_string = %Q{ 
... 
} 

private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file),password) 
string = private_key.private_decrypt(Base64.decode64(encrypted_string)) 

từ here

+2

Tôi không phải là người Rubyist, nhưng đó là những loại pin khá tốt. Tôi tự hỏi làm thế nào cứng tương đương sẽ được trong python ... – brice

+3

Chỉ muốn thêm các tập tin đó nên được mã hóa với, ví dụ, AES-256, nhưng khóa của nó nên được sended với rsa. – tiktak

+4

Tôi xin lỗi, nhưng đây thực sự là lời khuyên xấu. OP nói về mã hóa/giải mã tệp và bạn không bao giờ nên sử dụng RSA cho điều đó. – emboss

10

Tôi sợ bạn đang trộn hai khái niệm ở đây, xác thực/ủy quyền và bảo mật, cố gắng bao quát cả hai khía cạnh trong một bước duy nhất và điều đó sẽ không hoạt động. Bạn không bao giờ nên mã hóa "dữ liệu thực" với các thuật toán bất đối xứng. a) chúng quá chậm cho điều đó, b) có những vấn đề tinh tế, nếu không làm đúng, sẽ làm suy yếu nghiêm trọng sự an toàn của giải pháp của bạn.

Một nguyên tắc nhỏ là điều duy nhất bạn nên kết thúc việc mã hóa với tin bất đối xứng phím được đối xứng phím được sử dụng bởi một thuật toán nhanh hơn nhiều đối xứng. Nhưng trong hầu hết các trường hợp, bạn thậm chí không nên làm điều đó, bởi vì trong 90% các trường hợp bạn thực sự muốn là TLS (SSL) trong những trường hợp đó - tôi đã cố gắng giải thích tại sao here cách đây không lâu.

Trong trường hợp của bạn, tôi giả định các yêu cầu là:

  • tính bảo mật của dữ liệu mà là để được lưu trữ trong cơ sở dữ liệu: công chúng nói chung không nên có thể đọc nó (hoặc thậm chí truy cập vào nó)

  • một vài lựa chọn (có thể là chỉ một người) nên có thể truy cập và đọc dữ liệu

mục tiêu đầu tiên thường được thực hiện bằng cách sử dụng 012.. Mục tiêu thứ hai là, mặc dù có liên quan, được thực hiện bằng các phương tiện hoàn toàn khác nhau. Bạn muốn người dùng truy cập tệp được xác thực (tức là thiết lập danh tính) và trên hết bạn cũng muốn họ được ủy quyền (tức làkiểm tra xem danh tính đã được thiết lập có quyền làm những gì họ định làm). Đây là nơi mật mã không đối xứng có thể nhập giai đoạn, nhưng không nhất thiết. Vì câu hỏi của bạn được gắn thẻ với Rails, tôi cho rằng chúng ta đang nói về một ứng dụng Rails. Bạn thường có một số phương tiện để xác thực và ủy quyền cho người dùng ở đó (hầu hết có liên quan đến TLS được đề cập ở trên), bạn có thể sử dụng lại chúng để thiết lập khóa đối xứng để mã hóa/giải mã tệp thực. Password-based encryption sẽ phù hợp với mục đích này, nếu bạn muốn tránh mật mã bất đối xứng. Mọi thứ trở nên phức tạp hơn nếu bạn cũng muốn đảm bảo tính toàn vẹn của dữ liệu đã được bảo mật, nghĩa là bạn muốn cung cấp một loại bảo đảm cho người dùng được xác thực và được ủy quyền theo nghĩa là những gì họ truy cập cuối cùng không bị thay đổi theo bất kỳ cách nào trong luc đo.

Phát triển giải pháp cho việc này sẽ không có nhiệm vụ tầm thường và tùy thuộc vào yêu cầu của bạn, vì vậy tôi e rằng không có "cách vàng" phù hợp với mọi người. Tôi sẽ đề nghị làm một số nghiên cứu, có được một bức tranh rõ ràng hơn về những gì bạn đang cố gắng đạt được và làm thế nào, sau đó cố gắng nhận thêm lời khuyên về các chủ đề mà bạn vẫn cảm thấy không chắc chắn/không thoải mái.

+1

Cảm ơn bạn đã trả lời!Tôi đã giải quyết câu hỏi bằng cách chuyển và lưu trữ dữ liệu theo cách sau: 1) tạo khóa mã hóa đối xứng (khóa sym) 2) mã hóa các tệp bằng khóa sym-key 3) mã hóa khóa sym với khóa công khai 4) gửi tệp và mã hóa sym-key 5) giải mã user asym-key được mã hóa riêng với mã bí mật của người dùng 6) giải mã nhận sym-key bằng private asym-key 7) giải mã các tập tin với khóa sym-key đã được giải mã. Hãy nghĩ nó khá bình thường. – tiktak

+2

Đó là hướng đi đúng đắn! Nhưng nó vẫn còn dễ bị tấn công phát lại. Thay vì gửi một khóa được bao bọc bởi một khóa bất đối xứng, bạn không thể sử dụng TLS để thay thế? Tôi đã thấy rằng trong hầu hết các trường hợp bạn chuyển dữ liệu từ A sang B, bạn nên sử dụng TLS thay vì mật mã không đối xứng - TLS bảo vệ bạn chống lại những điều có khả năng nhất sẽ phá vỡ giao thức tùy chỉnh. – emboss

0

Tôi đã tạo ra một viên ngọc để trợ giúp việc này. Nó được gọi là cryptosystem. Đơn giản chỉ cần cấu hình đường dẫn và mật khẩu cho khóa riêng của bạn cũng như đường dẫn đến khóa công khai của bạn, và nó thực hiện phần còn lại.

Encrypting cũng đơn giản như:

rsa = Cryptosystem::RSA.new 
rsa.encrypt('secret') # => "JxpuhTpEqRtMLmaSfaq/X6XONkBnMe..." 

Và giải mã:

encrypted_value = rsa.encrypt('secret') # => "Y8DWJc2/+7TIxdLEolV99XI2sclHuK..." 
rsa.decrypt(encrypted_value) # => "secret" 

Bạn có thể kiểm tra xem nó ra trên GitHub hoặc RubyGems.

0

Symmetric Encryption chắc chắn là nhanh và có hỗ trợ tuyệt vời để phát trực tuyến các tệp rất lớn.

SymmetricEncryption::Writer.open('my_file.enc') do |file| 
    file.write "Hello World\n" 
    file.write "Keep this secret" 
end 

Mã hóa đối xứng được thiết kế để mã hóa dữ liệu và tệp lớn trong tổ chức.

Khi nói đến việc chia sẻ tệp với các tổ chức khác thì tùy chọn tốt nhất là PGP. Để phát trực tuyến các tập tin rất lớn với PGP xem xét: IOStreams

IOStreams.writer('hello.pgp', recipient: '[email protected]') do |writer| 
    writer.write('Hello World') 
    writer.write('and some more') 
end 

Nhìn vào iostreams tập tin/thư mục lib/io_streams/pgp.rb để biết thêm ví dụ PGP. Nó cũng hỗ trợ quản lý khóa PGP trực tiếp từ Ruby.

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