1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* ext/openssl/ossl.c: Fix error in example. Patch by David Albert.

Add/extend existing documentation. Examples now also cover RSA 
  signatures and PBKDF2.
  [ruby-core: 45154][ruby-trunk - Bug #6475]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35996 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
emboss 2012-06-09 18:16:18 +00:00
parent 14ba7fab58
commit 21f1af2ec2
2 changed files with 114 additions and 14 deletions

View file

@ -1,3 +1,12 @@
Sun Jun 10 03:09:41 2012 Martin Bosslet <Martin.Bosslet@googlemail.com>
* ext/openssl/ossl.c: Fix error in example. Patch by David Albert.
Add/extend existing documentation. Examples now also cover RSA
signatures and PBKDF2.
[ruby-core: 45154][ruby-trunk - Bug #6475]
Sun Jun 10 01:41:45 2012 Martin Bosslet <Martin.Bosslet@googlemail.com>
* ext/openssl/ossl_ssl.c: Introduce SSLContext#renegotiation_cb and

View file

@ -455,7 +455,7 @@ ossl_debug_set(VALUE self, VALUE val)
* ahold of the key may use it unless it is encrypted. In order to securely
* export a key you may export it with a pass phrase.
*
* cipher = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
* cipher = OpenSSL::Cipher.new 'AES-128-CBC'
* pass_phrase = 'my secure pass phrase goes here'
*
* key_secure = key.export cipher, pass_phrase
@ -489,35 +489,126 @@ ossl_debug_set(VALUE self, VALUE val)
*
* == RSA Encryption
*
* RSA provides ecryption and decryption using the public and private keys.
* RSA provides encryption and decryption using the public and private keys.
* You can use a variety of padding methods depending upon the intended use of
* encrypted data.
*
* === Encryption & Decryption
*
* Asymmetric public/private key encryption is slow and victim to attack in
* cases where it is used without padding or directly to encrypt larger chunks
* of data. Typical use cases for RSA encryption involve "wrapping" a symmetric
* key with the public key of the recipient who would "unwrap" that symmetric
* key again using their private key.
* The following illustrates a simplified example of such a key transport
* scheme. It shouldn't be used in practice, though, standardized protocols
* should always be preferred.
*
* wrapped_key = key.public_encrypt key
*
* A symmetric key encrypted with the public key can only be decrypted with
* the corresponding private key of the recipient.
*
* original_key = key.private_decrypt wrapped_key
*
* By default PKCS#1 padding will be used, but it is also possible to use
* other forms of padding, see PKey::RSA for further details.
*
* === Signatures
*
* Using "private_encrypt" to encrypt some data with the private key is
* equivalent to applying a digital signature to the data. A verifying
* party may validate the signature by comparing the result of decrypting
* the signature with "public_decrypt" to the original data. However,
* OpenSSL::PKey already has methods "sign" and "verify" that handle
* digital signatures in a standardized way - "private_encrypt" and
* "public_decrypt" shouldn't be used in practice.
*
* To sign a document, a cryptographically secure hash of the document is
* computed first, which is then signed using the private key.
*
* digest = OpenSSL::Digest::SHA256.new
* signature = key.sign digest, document
*
* To validate the signature, again a hash of the document is computed and
* the signature is decrypted using the public key. The result is then
* compared to the hash just computed, if they are equal the signature was
* valid.
*
* digest = OpenSSL::Digest::SHA256.new
* if key.verify digest, signature, document
* puts 'Valid'
* else
* puts 'Invalid'
* end
*
* == PBKDF2 Password-based Encryption
*
* If supported by the underlying OpenSSL version used, Password-based
* Encryption should use the features of PKCS5. If not supported or if
* required by legacy applications, the older, less secure methods specified
* in RFC 2898 are also supported (see below).
*
* PKCS5 supports PBKDF2 as it was specified in PKCS#5
* v2.0[http://www.rsa.com/rsalabs/node.asp?id=2127]. It still uses a
* password, a salt, and additionally a number of iterations that will
* slow the key derivation process down. The slower this is, the more work
* it requires being able to brute-force the resulting key.
*
* === Encryption
*
* The strategy is to first instantiate a Cipher for encryption, and
* then to generate a random IV plus a key derived from the password
* using PBKDF2. PKCS #5 v2.0 recommends at least 8 bytes for the salt,
* the number of iterations largely depends on the hardware being used.
*
* Documents encrypted with the public key can only be decrypted with the
* private key.
* cipher = OpenSSL::Cipher.new 'AES-128-CBC'
* cipher.encrypt
* iv = cipher.random_iv
*
* public_encrypted = key.public_encrypt 'top secret document'
* pwd = 'some hopefully not to easily guessable password'
* salt = OpenSSL::Random.random_bytes 16
* iter = 20000
* key_len = cipher.key_len
* digest = OpenSSL::Digest::SHA256.new
*
* Documents encrypted with the private key can only be decrypted with the
* public key.
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
* cipher.key = key
*
* private_encrypted = key.private_encrypt 'public release document'
* Now encrypt the data:
*
* encrypted = cipher.update document
* encrypted << cipher.final
*
* === Decryption
*
* Use the opposite key type do decrypt the document
* Use the same steps as before to derive the symmetric AES key, this time
* setting the Cipher up for decryption.
*
* top_secret = key.public_decrypt public_encrypted
* cipher = OpenSSL::Cipher.new 'AES-128-CBC'
* cipher.decrypt
* cipher.iv = iv # the one generated with #random_iv
*
* public_release = key.private_decrypt private_encrypted
* pwd = 'some hopefully not to easily guessable password'
* salt = ... # the one generated above
* iter = 20000
* key_len = cipher.key_len
* digest = OpenSSL::Digest::SHA256.new
*
* key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
* cipher.key = key
*
* Now decrypt the data:
*
* decrypted = cipher.update encrypted
* decrypted << cipher.final
*
* == PKCS #5 Password-based Encryption
*
* PKCS #5 is a password-based encryption standard documented at
* RFC2898[http://www.ietf.org/rfc/rfc2898.txt]. It allows a short password or
* passphrase to be used to create a secure encryption key.
* passphrase to be used to create a secure encryption key. If possible, PBKDF2
* as described above should be used if the circumstances allow it.
*
* PKCS #5 uses a Cipher, a pass phrase and a salt to generate an encryption
* key.
@ -529,7 +620,7 @@ ossl_debug_set(VALUE self, VALUE val)
*
* First set up the cipher for encryption
*
* encrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
* encrypter = OpenSSL::Cipher.new 'AES-128-CBC'
* encrypter.encrypt
* encrypter.pkcs5_keyivgen pass_phrase, salt
*
@ -542,7 +633,7 @@ ossl_debug_set(VALUE self, VALUE val)
*
* Use a new Cipher instance set up for decryption
*
* decrypter = OpenSSL::Cipher::Cipher.new 'AES-128-CBC'
* decrypter = OpenSSL::Cipher.new 'AES-128-CBC'
* decrypter.decrypt
* decrypter.pkcs5_keyivgen pass_phrase, salt
*