如何使用以下约束在Ruby中创建加密文件?
注意:在误解后澄清问题。
答案 0 :(得分:2)
如果您安装了GPG,那么可以采用快速,简便,可靠的方式:
open("| gpg [options]","w"){|f| f.syswrite(data) }
示例:
require 'shellwords'
data = "Hello World"
password = "letmein"
gpg = "/usr/local/bin/gpg \
--symmetric \
--cipher-algo aes256 \
--digest-algo sha256 \
--cert-digest-algo sha256 \
--batch --yes \
--passphrase #{password.shellescape} \
--output /tmp/out.gpg
"
open("| #{gpg}","w"){|f| f.syswrite(data) }
通常,使用系统的内置GPG更安全,而不是尝试管理自己的加密。
答案 1 :(得分:0)
解决了这个问题,而无需通过与openssl进行互操作来生成进程:
更新:请参阅我使用gpg的其他答案
@@OPENSSL_MAGIC = "Salted__"
@@DEFAULT_CIPHER = "aes-256-cbc"
@@DEFAULT_MD = OpenSSL::Digest::SHA256
# Note: OpenSSL "enc" uses a non-standard file format with a custom key
# derivation function and a fixed iteration count of 1, which some consider
# less secure than alternatives such as OpenPGP/GnuPG
#
# Resulting bytes when written to #{FILE} may be decrypted from the command
# line with `openssl enc -d -#{cipher} -md #{md} -in #{FILE}`
#
# Example:
# openssl enc -d -aes-256-cbc -md sha256 -in file.encrypted
def encrypt_for_openssl(
password,
data,
cipher = @@DEFAULT_CIPHER,
md = @@DEFAULT_MD.new
)
salt = SecureRandom.random_bytes(8)
cipher = OpenSSL::Cipher::Cipher.new(cipher)
cipher.encrypt
cipher.pkcs5_keyivgen(password, salt, 1, md)
encrypted_data = cipher.update(data) + cipher.final
@@OPENSSL_MAGIC + salt + encrypted_data
end
# Data may be written from the command line with
# `openssl enc -#{cipher} -md #{md} -in #{INFILE} -out #{OUTFILE}`
# and the resulting bytes may be read by this function.
#
# Example:
# openssl enc -aes-256-cbc -md sha256 -in file.txt -out file.txt.encrypted
def decrypt_from_openssl(
password,
data,
cipher = @@DEFAULT_CIPHER,
md = @@DEFAULT_MD.new
)
input_magic = data.slice!(0, 8)
input_salt = data.slice!(0, 8)
cipher = OpenSSL::Cipher::Cipher.new(cipher)
cipher.decrypt
cipher.pkcs5_keyivgen(password, input_salt, 1, md)
c.update(data) + c.final
end
这基于forge.js security library,特别是example to match openssl's enc tool和using an iteration count of 1。
答案 2 :(得分:0)
ruby-gpgme和openpgp似乎都不行,因此产生gpg似乎是目前最好的方法。
require "openssl"
require "digest/sha2"
require "open3"
require "tempfile"
....
@@OPENPGP_DEFAULT_CIPHER = "AES256"
@@DEFAULT_MD = OpenSSL::Digest::SHA512
# Return symmetrically encrypted bytes in RFC 4880 format which can be
# read by GnuPG or PGP. For example:
# $ gpg --decrypt file.pgp
#
# ruby-gpgme doesn't seem to work: https://github.com/ueno/ruby-gpgme/issues/11
# openpgp doesn't seem to work: https://github.com/bendiken/openpgp/issues/2
# Therefore we assume gpg is installed and try to spawn out to it
def encrypt_for_pgp(
password,
data,
cipher = @@OPENPGP_DEFAULT_CIPHER,
md = @@DEFAULT_MD.new
)
input_file = Tempfile.new('input')
begin
input_file.write(data)
input_file.close
output_file = Tempfile.new('output')
begin
Open3.popen3(
"gpg --batch --passphrase-fd 0 --yes --homedir /tmp/ " +
"--cipher-algo #{cipher} --s2k-digest-algo #{md.name} " +
"-o #{output_file.path} --symmetric #{input_file.path}"
) do |stdin, stdout, stderr, wait_thr|
stdin.write(password)
stdin.close_write
exit_status = wait_thr.value
if exit_status != 0
raise "Exit status " + exit_status.to_s
end
end
output_file.close
return IO.binread(output_file.path)
ensure
output_file.unlink
end
ensure
input_file.unlink
end
end