2012-06-15 46 views
11

Tôi cần phải viết một công cụ đơn giản mã hóa/giải mã các tệp.Làm thế nào để mã hóa các tệp bằng Ruby?

Tôi đoán cách tốt nhất là sử dụng OpenSSL:

Tạo một chìa khóa:

openssl rand -base64 2048 > secret_key 

Mã hóa một tập tin:

openssl aes-256-cbc -a -e -in file -out file.enc -k secret_key 

Giải mã một tập tin:

openssl aes-256-cbc -d -in file.enc -out file -k secret_key 

Có cách nào dễ dàng để thực hiện điều này trong Ruby? Có cách nào tốt hơn để làm điều đó không? Sử dụng PGP có thể?

+1

Vì vậy, những gì chính xác câu hỏi: sử dụng OpenSSL mà không cần phải gọi một chương trình bên ngoài? –

+0

lệnh để giải mã phải là: 'openssl aes-256-cbc -d -a -in tập tin.enc-out tập tin -k secret_key' hoặc nếu không bạn sẽ nhận được một' số ma thuật xấu' – aelor

Trả lời

17

Ruby OpenSSL là một wrapper mỏng xung quanh OpenSSL bản thân và cung cấp gần như tất cả các chức năng mà OpenSSL chính nó, vì vậy có, có một one-to-one lập bản đồ cho tất cả các ví dụ của bạn:

openssl rand -base64 2048 > secret_key 

Đó thực sự phóng đại , bạn đang sử dụng AES-256, vì vậy bạn chỉ cần một khóa 256 bit, bạn không sử dụng RSA ở đây. Ruby OpenSSL đưa quyết định này ra khỏi vai của bạn, nó sẽ tự động xác định kích thước khóa chính xác cho thuật toán bạn muốn sử dụng.

Bạn cũng đang mắc lỗi khi sử dụng số IV xác định trong quá trình mã hóa của mình. Tại sao? Bởi vì bạn không chỉ định một IV ở tất cả, OpenSSL chính nó sẽ mặc định là một IV của tất cả các byte không. Đó không phải là một điều tốt, vì vậy tôi sẽ chỉ cho bạn cách chính xác để làm điều đó, để biết thêm thông tin có một cái nhìn tại Cipher documentation.

require 'openssl' 

# encryption 
cipher = OpenSSL::Cipher.new('aes-256-cbc') 
cipher.encrypt 
key = cipher.random_key 
iv = cipher.random_iv 

buf = "" 
File.open("file.enc", "wb") do |outf| 
    File.open("file", "rb") do |inf| 
    while inf.read(4096, buf) 
     outf << cipher.update(buf) 
    end 
    outf << cipher.final 
    end 
end 

# decryption 
cipher = OpenSSL::Cipher.new('aes-256-cbc') 
cipher.decrypt 
cipher.key = key 
cipher.iv = iv # key and iv are the ones from above 

buf = "" 
File.open("file.dec", "wb") do |outf| 
    File.open("file.enc", "rb") do |inf| 
    while inf.read(4096, buf) 
     outf << cipher.update(buf) 
    end 
    outf << cipher.final 
    end 
end 

Như bạn thấy, mã hóa và giải mã tương đối giống nhau, vì vậy bạn có thể kết hợp việc đọc trực tuyến/viết thành một phương pháp chia sẻ và chỉ vượt qua nó một cấu hình đúng Cipher cộng với tên file tương ứng, tôi chỉ nói chúng rõ ràng vì lợi ích của sự rõ ràng.

Nếu bạn muốn Base64 mã hóa phím (và có lẽ là IV, quá), bạn có thể sử dụng các mô-đun Base64:

base64_key = Base64.encode64(key) 
+1

Tôi tự hỏi nếu câu trả lời này cần bất kỳ bản cập nhật hay không, nếu như vậy nó sẽ được như vậy tốt đẹp để thêm một số. –

4

Ruby có số OpenSSL library cần chú ý đến việc nâng vật nặng.

+0

Cảm ơn. Tôi có thể cần phải chuyển sang PGP vì nó hỗ trợ PKI cho các tệp (tôi có các tệp nhỏ) nên tôi có thể dễ dàng hỗ trợ nhiều người dùng mà không gặp sự cố khi lưu trữ khóa bí mật. – Istvan

+0

@Istvan Có hỗ trợ PKI trong OpenSSL. – emboss

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