Does anyone know if ruby implements something similar to the openssl_seal function from PHP? I'd like to be able to interact with a server running a modified implementation of this answer. The PHP solution is pretty simple and it'd be great if I could find something for开发者_StackOverflow社区 Ruby to do the same.
Somebody was looking for the same for python a year ago, but didn't find anything.
EVP_Seal does simple wrapping with RSA so you can do it manually with OpenSSL features.
Here's a PHP script that does seal with 1 cert:
<?php
$pubkey = openssl_pkey_get_public(file_get_contents('selfcert.pem'));
$message = 'hello,world';
$cipher_text = NULL;
$keys = NULL;
openssl_seal($message, $cipher_text, $keys, array($pubkey));
$file = fopen('wrapped.bin', 'wb');
fwrite($file, $keys[0]);
fclose($file);
$file = fopen('data.bin', 'wb');
fwrite($file, $cipher_text);
fclose($file);
?>
and a Ruby script that unseal it:
require 'openssl'
wrapped = File.read('wrapped.bin')
cipher_text = File.read('data.bin')
privkey = OpenSSL::PKey::RSA.new(File.read('privkey.pem'))
key = privkey.private_decrypt(wrapped)
cipher = OpenSSL::Cipher.new('rc4')
cipher.decrypt
cipher.key = key
p cipher.update(cipher_text) + cipher.final
You can do 'seal' with Ruby as well but creating secure session key (RC4 key for this example) is rather difficult so you'd better not try to do by yourself.
The PHP documentation is a bit unclear on what openssl_seal
does exactly, however its source is pretty short (look for PHP_FUNCTION(openssl_seal)
in ext/openssl/openssl.c
, online here at http://svn.php.net/viewvc/php/php-src/trunk/ext/openssl/openssl.c?view=markup).
It's a wrapper on an EVP_SealIinit()
, EVP_Seal_Update()
, EVP_Seal_Final()
sequence (see http://www.openssl.org/docs/crypto/EVP_SealInit.html). As far as I can see those OpenSSL functions are not exposed by the OpenSSL Ruby module, nor by the openssl
command line tool, so if you really want to pursue this road I guess you are down to two options:
- using FFI to call those functions from Ruby
- building a small extension in C (what I think is the best route, as you already have working C source and OpenSSL "Seal" in C (or via shell) got some good pointers too)
Envelope encryption does two things:
- Encrypts your data using symmetric encryption (via a random key). This is fast and outputs data of comparable size.
- Uses asymmetric encryption to encrypt the random key. This is fast because the data size is small.
It'd be nice if this was in Ruby's bindings to OpenSSL, but you can do this yourself. Essentially what you do is:
- Generate a random IV and symmetric key (K1)
- Encrypt your plaintext (PT) with K1, getting ciphertext (CT) as a result
At this point, to decrypt the CT to PT, you need both K1 and the IV. We need to transfer K1 in a secure fashion:
- Encrypt K1 using a public key to get EK1
- Transfer
The consumer now needs to reverse the process. The ultimate goal is to turn the ciphertext (CT) back into plaintext (PT). To do that we need to undo the symmetric encryption done using K1.
- Unwrap the encrypted EK1 by decrypting it using the private key and the IV
- Decrypt the CT using K1
Something like this should do the trick: https://gist.github.com/1899731
精彩评论