Ruby 1.9.3p327(2012-11-10revision37606)
|
00001 /* 00002 * $Id: ossl_cipher.c 34505 2012-02-09 03:25:07Z nobu $ 00003 * 'OpenSSL for Ruby' project 00004 * Copyright (C) 2001-2002 Michal Rokos <m.rokos@sh.cvut.cz> 00005 * All rights reserved. 00006 */ 00007 /* 00008 * This program is licenced under the same licence as Ruby. 00009 * (See the file 'LICENCE'.) 00010 */ 00011 #include "ossl.h" 00012 00013 #define WrapCipher(obj, klass, ctx) \ 00014 (obj) = Data_Wrap_Struct((klass), 0, ossl_cipher_free, (ctx)) 00015 #define MakeCipher(obj, klass, ctx) \ 00016 (obj) = Data_Make_Struct((klass), EVP_CIPHER_CTX, 0, ossl_cipher_free, (ctx)) 00017 #define AllocCipher(obj, ctx) \ 00018 memset(DATA_PTR(obj) = (ctx) = ALLOC(EVP_CIPHER_CTX), 0, sizeof(EVP_CIPHER_CTX)) 00019 #define GetCipherInit(obj, ctx) do { \ 00020 Data_Get_Struct((obj), EVP_CIPHER_CTX, (ctx)); \ 00021 } while (0) 00022 #define GetCipher(obj, ctx) do { \ 00023 GetCipherInit((obj), (ctx)); \ 00024 if (!(ctx)) { \ 00025 ossl_raise(rb_eRuntimeError, "Cipher not inititalized!"); \ 00026 } \ 00027 } while (0) 00028 #define SafeGetCipher(obj, ctx) do { \ 00029 OSSL_Check_Kind((obj), cCipher); \ 00030 GetCipher((obj), (ctx)); \ 00031 } while (0) 00032 00033 /* 00034 * Classes 00035 */ 00036 VALUE cCipher; 00037 VALUE eCipherError; 00038 00039 static VALUE ossl_cipher_alloc(VALUE klass); 00040 00041 /* 00042 * PUBLIC 00043 */ 00044 const EVP_CIPHER * 00045 GetCipherPtr(VALUE obj) 00046 { 00047 EVP_CIPHER_CTX *ctx; 00048 00049 SafeGetCipher(obj, ctx); 00050 00051 return EVP_CIPHER_CTX_cipher(ctx); 00052 } 00053 00054 VALUE 00055 ossl_cipher_new(const EVP_CIPHER *cipher) 00056 { 00057 VALUE ret; 00058 EVP_CIPHER_CTX *ctx; 00059 00060 ret = ossl_cipher_alloc(cCipher); 00061 AllocCipher(ret, ctx); 00062 EVP_CIPHER_CTX_init(ctx); 00063 if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) 00064 ossl_raise(eCipherError, NULL); 00065 00066 return ret; 00067 } 00068 00069 /* 00070 * PRIVATE 00071 */ 00072 static void 00073 ossl_cipher_free(EVP_CIPHER_CTX *ctx) 00074 { 00075 if (ctx) { 00076 EVP_CIPHER_CTX_cleanup(ctx); 00077 ruby_xfree(ctx); 00078 } 00079 } 00080 00081 static VALUE 00082 ossl_cipher_alloc(VALUE klass) 00083 { 00084 VALUE obj; 00085 00086 WrapCipher(obj, klass, 0); 00087 00088 return obj; 00089 } 00090 00091 /* 00092 * call-seq: 00093 * Cipher.new(string) -> cipher 00094 * 00095 * The string must contain a valid cipher name like "AES-128-CBC" or "3DES". 00096 * 00097 * A list of cipher names is available by calling OpenSSL::Cipher.ciphers. 00098 */ 00099 static VALUE 00100 ossl_cipher_initialize(VALUE self, VALUE str) 00101 { 00102 EVP_CIPHER_CTX *ctx; 00103 const EVP_CIPHER *cipher; 00104 char *name; 00105 unsigned char key[EVP_MAX_KEY_LENGTH]; 00106 00107 name = StringValuePtr(str); 00108 GetCipherInit(self, ctx); 00109 if (ctx) { 00110 ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); 00111 } 00112 AllocCipher(self, ctx); 00113 EVP_CIPHER_CTX_init(ctx); 00114 if (!(cipher = EVP_get_cipherbyname(name))) { 00115 ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name); 00116 } 00117 /* 00118 * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows 00119 * uninitialized key, but other EVPs (such as AES) does not allow it. 00120 * Calling EVP_CipherUpdate() without initializing key causes SEGV so we 00121 * set the data filled with "\0" as the key by default. 00122 */ 00123 memset(key, 0, EVP_MAX_KEY_LENGTH); 00124 if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1) 00125 ossl_raise(eCipherError, NULL); 00126 00127 return self; 00128 } 00129 00130 static VALUE 00131 ossl_cipher_copy(VALUE self, VALUE other) 00132 { 00133 EVP_CIPHER_CTX *ctx1, *ctx2; 00134 00135 rb_check_frozen(self); 00136 if (self == other) return self; 00137 00138 GetCipherInit(self, ctx1); 00139 if (!ctx1) { 00140 AllocCipher(self, ctx1); 00141 } 00142 SafeGetCipher(other, ctx2); 00143 if (EVP_CIPHER_CTX_copy(ctx1, ctx2) != 1) 00144 ossl_raise(eCipherError, NULL); 00145 00146 return self; 00147 } 00148 00149 #ifdef HAVE_OBJ_NAME_DO_ALL_SORTED 00150 static void* 00151 add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary) 00152 { 00153 rb_ary_push(ary, rb_str_new2(name->name)); 00154 return NULL; 00155 } 00156 #endif 00157 00158 #ifdef HAVE_OBJ_NAME_DO_ALL_SORTED 00159 /* 00160 * call-seq: 00161 * Cipher.ciphers -> array[string...] 00162 * 00163 * Returns the names of all available ciphers in an array. 00164 */ 00165 static VALUE 00166 ossl_s_ciphers(VALUE self) 00167 { 00168 VALUE ary; 00169 00170 ary = rb_ary_new(); 00171 OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, 00172 (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary, 00173 (void*)ary); 00174 00175 return ary; 00176 } 00177 #else 00178 #define ossl_s_ciphers rb_f_notimplement 00179 #endif 00180 00181 /* 00182 * call-seq: 00183 * cipher.reset -> self 00184 * 00185 * Fully resets the internal state of the Cipher. By using this, the same 00186 * Cipher instance may be used several times for en- or decryption tasks. 00187 * 00188 * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1). 00189 */ 00190 static VALUE 00191 ossl_cipher_reset(VALUE self) 00192 { 00193 EVP_CIPHER_CTX *ctx; 00194 00195 GetCipher(self, ctx); 00196 if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1) 00197 ossl_raise(eCipherError, NULL); 00198 00199 return self; 00200 } 00201 00202 static VALUE 00203 ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode) 00204 { 00205 EVP_CIPHER_CTX *ctx; 00206 unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL; 00207 unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL; 00208 VALUE pass, init_v; 00209 00210 if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){ 00211 /* 00212 * oops. this code mistakes salt for IV. 00213 * We deprecated the arguments for this method, but we decided 00214 * keeping this behaviour for backward compatibility. 00215 */ 00216 const char *cname = rb_class2name(rb_obj_class(self)); 00217 rb_warn("arguments for %s#encrypt and %s#decrypt were deprecated; " 00218 "use %s#pkcs5_keyivgen to derive key and IV", 00219 cname, cname, cname); 00220 StringValue(pass); 00221 GetCipher(self, ctx); 00222 if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv)); 00223 else{ 00224 StringValue(init_v); 00225 if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) { 00226 memset(iv, 0, EVP_MAX_IV_LENGTH); 00227 memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v)); 00228 } 00229 else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv)); 00230 } 00231 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv, 00232 (unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL); 00233 p_key = key; 00234 p_iv = iv; 00235 } 00236 else { 00237 GetCipher(self, ctx); 00238 } 00239 if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) { 00240 ossl_raise(eCipherError, NULL); 00241 } 00242 00243 return self; 00244 } 00245 00246 /* 00247 * call-seq: 00248 * cipher.encrypt -> self 00249 * 00250 * Initializes the Cipher for encryption. 00251 * 00252 * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the 00253 * following methods: 00254 * * [key=, iv=, random_key, random_iv, pkcs5_keyivgen] 00255 * 00256 * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1). 00257 */ 00258 static VALUE 00259 ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self) 00260 { 00261 return ossl_cipher_init(argc, argv, self, 1); 00262 } 00263 00264 /* 00265 * call-seq: 00266 * cipher.decrypt -> self 00267 * 00268 * Initializes the Cipher for decryption. 00269 * 00270 * Make sure to call Cipher#encrypt or Cipher#decrypt before using any of the 00271 * following methods: 00272 * * [key=, iv=, random_key, random_iv, pkcs5_keyivgen] 00273 * 00274 * Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0). 00275 */ 00276 static VALUE 00277 ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self) 00278 { 00279 return ossl_cipher_init(argc, argv, self, 0); 00280 } 00281 00282 /* 00283 * call-seq: 00284 * cipher.pkcs5_keyivgen(pass [, salt [, iterations [, digest]]] ) -> nil 00285 * 00286 * Generates and sets the key/IV based on a password. 00287 * 00288 * WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, 00289 * or DES with MD5 or SHA1. Using anything else (like AES) will generate the 00290 * key/iv using an OpenSSL specific method. This method is deprecated and 00291 * should no longer be used. Use a PKCS5 v2 key generation method from 00292 * OpenSSL::PKCS5 instead. 00293 * 00294 * === Parameters 00295 * +salt+ must be an 8 byte string if provided. 00296 * +iterations+ is a integer with a default of 2048. 00297 * +digest+ is a Digest object that defaults to 'MD5' 00298 * 00299 * A minimum of 1000 iterations is recommended. 00300 * 00301 */ 00302 static VALUE 00303 ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self) 00304 { 00305 EVP_CIPHER_CTX *ctx; 00306 const EVP_MD *digest; 00307 VALUE vpass, vsalt, viter, vdigest; 00308 unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL; 00309 int iter; 00310 00311 rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest); 00312 StringValue(vpass); 00313 if(!NIL_P(vsalt)){ 00314 StringValue(vsalt); 00315 if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN) 00316 ossl_raise(eCipherError, "salt must be an 8-octet string"); 00317 salt = (unsigned char *)RSTRING_PTR(vsalt); 00318 } 00319 iter = NIL_P(viter) ? 2048 : NUM2INT(viter); 00320 digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest); 00321 GetCipher(self, ctx); 00322 EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt, 00323 (unsigned char *)RSTRING_PTR(vpass), RSTRING_LENINT(vpass), iter, key, iv); 00324 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1) 00325 ossl_raise(eCipherError, NULL); 00326 OPENSSL_cleanse(key, sizeof key); 00327 OPENSSL_cleanse(iv, sizeof iv); 00328 00329 return Qnil; 00330 } 00331 00332 00333 /* 00334 * call-seq: 00335 * cipher.update(data [, buffer]) -> string or buffer 00336 * 00337 * Encrypts data in a streaming fashion. Hand consecutive blocks of data 00338 * to the +update+ method in order to encrypt it. Returns the encrypted 00339 * data chunk. When done, the output of Cipher#final should be additionally 00340 * added to the result. 00341 * 00342 * === Parameters 00343 * +data+ is a nonempty string. 00344 * +buffer+ is an optional string to store the result. 00345 */ 00346 static VALUE 00347 ossl_cipher_update(int argc, VALUE *argv, VALUE self) 00348 { 00349 EVP_CIPHER_CTX *ctx; 00350 unsigned char *in; 00351 int in_len, out_len; 00352 VALUE data, str; 00353 00354 rb_scan_args(argc, argv, "11", &data, &str); 00355 00356 StringValue(data); 00357 in = (unsigned char *)RSTRING_PTR(data); 00358 if ((in_len = RSTRING_LENINT(data)) == 0) 00359 ossl_raise(rb_eArgError, "data must not be empty"); 00360 GetCipher(self, ctx); 00361 out_len = in_len+EVP_CIPHER_CTX_block_size(ctx); 00362 00363 if (NIL_P(str)) { 00364 str = rb_str_new(0, out_len); 00365 } else { 00366 StringValue(str); 00367 rb_str_resize(str, out_len); 00368 } 00369 00370 if (!EVP_CipherUpdate(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len)) 00371 ossl_raise(eCipherError, NULL); 00372 assert(out_len < RSTRING_LEN(str)); 00373 rb_str_set_len(str, out_len); 00374 00375 return str; 00376 } 00377 00378 /* 00379 * call-seq: 00380 * cipher.final -> string 00381 * 00382 * Returns the remaining data held in the cipher object. Further calls to 00383 * Cipher#update or Cipher#final will return garbage. 00384 * 00385 * See EVP_CipherFinal_ex for further information. 00386 */ 00387 static VALUE 00388 ossl_cipher_final(VALUE self) 00389 { 00390 EVP_CIPHER_CTX *ctx; 00391 int out_len; 00392 VALUE str; 00393 00394 GetCipher(self, ctx); 00395 str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx)); 00396 if (!EVP_CipherFinal_ex(ctx, (unsigned char *)RSTRING_PTR(str), &out_len)) 00397 ossl_raise(eCipherError, NULL); 00398 assert(out_len <= RSTRING_LEN(str)); 00399 rb_str_set_len(str, out_len); 00400 00401 return str; 00402 } 00403 00404 /* 00405 * call-seq: 00406 * cipher.name -> string 00407 * 00408 * Returns the name of the cipher which may differ slightly from the original 00409 * name provided. 00410 */ 00411 static VALUE 00412 ossl_cipher_name(VALUE self) 00413 { 00414 EVP_CIPHER_CTX *ctx; 00415 00416 GetCipher(self, ctx); 00417 00418 return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx))); 00419 } 00420 00421 /* 00422 * call-seq: 00423 * cipher.key = string -> string 00424 * 00425 * Sets the cipher key. To generate a key, you should either use a secure 00426 * random byte string or, if the key is to be derived from a password, you 00427 * should rely on PBKDF2 functionality provided by OpenSSL::PKCS5. To 00428 * generate a secure random-based key, Cipher#random_key may be used. 00429 * 00430 * Only call this method after calling Cipher#encrypt or Cipher#decrypt. 00431 */ 00432 static VALUE 00433 ossl_cipher_set_key(VALUE self, VALUE key) 00434 { 00435 EVP_CIPHER_CTX *ctx; 00436 00437 StringValue(key); 00438 GetCipher(self, ctx); 00439 00440 if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx)) 00441 ossl_raise(eCipherError, "key length too short"); 00442 00443 if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1) 00444 ossl_raise(eCipherError, NULL); 00445 00446 return key; 00447 } 00448 00449 /* 00450 * call-seq: 00451 * cipher.iv = string -> string 00452 * 00453 * Sets the cipher IV. Please note that since you should never be using ECB 00454 * mode, an IV is always explicitly required and should be set prior to 00455 * encryption. The IV itself can be safely transmitted in public, but it 00456 * should be unpredictable to prevent certain kinds of attacks. You may use 00457 * Cipher#random_iv to create a secure random IV. 00458 * 00459 * Only call this method after calling Cipher#encrypt or Cipher#decrypt. 00460 * 00461 * If not explicitly set, the OpenSSL default of an all-zeroes ("\\0") IV is 00462 * used. 00463 */ 00464 static VALUE 00465 ossl_cipher_set_iv(VALUE self, VALUE iv) 00466 { 00467 EVP_CIPHER_CTX *ctx; 00468 00469 StringValue(iv); 00470 GetCipher(self, ctx); 00471 00472 if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx)) 00473 ossl_raise(eCipherError, "iv length too short"); 00474 00475 if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1) 00476 ossl_raise(eCipherError, NULL); 00477 00478 return iv; 00479 } 00480 00481 00482 /* 00483 * call-seq: 00484 * cipher.key_len = integer -> integer 00485 * 00486 * Sets the key length of the cipher. If the cipher is a fixed length cipher 00487 * then attempting to set the key length to any value other than the fixed 00488 * value is an error. 00489 * 00490 * Under normal circumstances you do not need to call this method (and probably shouldn't). 00491 * 00492 * See EVP_CIPHER_CTX_set_key_length for further information. 00493 */ 00494 static VALUE 00495 ossl_cipher_set_key_length(VALUE self, VALUE key_length) 00496 { 00497 int len = NUM2INT(key_length); 00498 EVP_CIPHER_CTX *ctx; 00499 00500 GetCipher(self, ctx); 00501 if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1) 00502 ossl_raise(eCipherError, NULL); 00503 00504 return key_length; 00505 } 00506 00507 #if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING) 00508 /* 00509 * call-seq: 00510 * cipher.padding = integer -> integer 00511 * 00512 * Enables or disables padding. By default encryption operations are padded using standard block padding and the 00513 * padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the 00514 * total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur. 00515 * 00516 * See EVP_CIPHER_CTX_set_padding for further information. 00517 */ 00518 static VALUE 00519 ossl_cipher_set_padding(VALUE self, VALUE padding) 00520 { 00521 EVP_CIPHER_CTX *ctx; 00522 int pad = NUM2INT(padding); 00523 00524 GetCipher(self, ctx); 00525 if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1) 00526 ossl_raise(eCipherError, NULL); 00527 return padding; 00528 } 00529 #else 00530 #define ossl_cipher_set_padding rb_f_notimplement 00531 #endif 00532 00533 #define CIPHER_0ARG_INT(func) \ 00534 static VALUE \ 00535 ossl_cipher_##func(VALUE self) \ 00536 { \ 00537 EVP_CIPHER_CTX *ctx; \ 00538 GetCipher(self, ctx); \ 00539 return INT2NUM(EVP_CIPHER_##func(EVP_CIPHER_CTX_cipher(ctx))); \ 00540 } 00541 00542 /* 00543 * call-seq: 00544 * cipher.key_len -> integer 00545 * 00546 * Returns the key length in bytes of the Cipher. 00547 */ 00548 CIPHER_0ARG_INT(key_length) 00549 /* 00550 * call-seq: 00551 * cipher.iv_len -> integer 00552 * 00553 * Returns the expected length in bytes for an IV for this Cipher. 00554 */ 00555 CIPHER_0ARG_INT(iv_length) 00556 /* 00557 * call-seq: 00558 * cipher.block_size -> integer 00559 * 00560 * Returns the size in bytes of the blocks on which this Cipher operates on. 00561 */ 00562 CIPHER_0ARG_INT(block_size) 00563 00564 /* 00565 * INIT 00566 */ 00567 void 00568 Init_ossl_cipher(void) 00569 { 00570 #if 0 00571 mOSSL = rb_define_module("OpenSSL"); /* let rdoc know about mOSSL */ 00572 #endif 00573 00574 /* Document-class: OpenSSL::Cipher 00575 * 00576 * Provides symmetric algorithms for encryption and decryption. The 00577 * algorithms that are available depend on the particular version 00578 * of OpenSSL that is installed. 00579 * 00580 * === Listing all supported algorithms 00581 * 00582 * A list of supported algorithms can be obtained by 00583 * 00584 * puts OpenSSL::Cipher.ciphers 00585 * 00586 * === Instantiating a Cipher 00587 * 00588 * There are several ways to create a Cipher instance. Generally, a 00589 * Cipher algorithm is categorized by its name, the key length in bits 00590 * and the cipher mode to be used. The most generic way to create a 00591 * Cipher is the following 00592 * 00593 * cipher = OpenSSL::Cipher.new('<name>-<key length>-<mode>') 00594 * 00595 * That is, a string consisting of the hyphenated concatenation of the 00596 * individual components name, key length and mode. Either all uppercase 00597 * or all lowercase strings may be used, for example: 00598 * 00599 * cipher = OpenSSL::Cipher.new('AES-128-CBC') 00600 * 00601 * For each algorithm supported, there is a class defined under the 00602 * Cipher class that goes by the name of the cipher, e.g. to obtain an 00603 * instance of AES, you could also use 00604 * 00605 * # these are equivalent 00606 * cipher = OpenSSL::Cipher::AES.new(128, :CBC) 00607 * cipher = OpenSSL::Cipher::AES.new(128, 'CBC') 00608 * cipher = OpenSSL::Cipher::AES.new('128-CBC') 00609 * 00610 * Finally, due to its wide-spread use, there are also extra classes 00611 * defined for the different key sizes of AES 00612 * 00613 * cipher = OpenSSL::Cipher::AES128.new(:CBC) 00614 * cipher = OpenSSL::Cipher::AES192.new(:CBC) 00615 * cipher = OpenSSL::Cipher::AES256.new(:CBC) 00616 * 00617 * === Choosing either encryption or decryption mode 00618 * 00619 * Encryption and decryption are often very similar operations for 00620 * symmetric algorithms, this is reflected by not having to choose 00621 * different classes for either operation, both can be done using the 00622 * same class. Still, after obtaining a Cipher instance, we need to 00623 * tell the instance what it is that we intend to do with it, so we 00624 * need to call either 00625 * 00626 * cipher.encrypt 00627 * 00628 * or 00629 * 00630 * cipher.decrypt 00631 * 00632 * on the Cipher instance. This should be the first call after creating 00633 * the instance, otherwise configuration that has already been set could 00634 * get lost in the process. 00635 * 00636 * === Choosing a key 00637 * 00638 * Symmetric encryption requires a key that is the same for the encrypting 00639 * and for the decrypting party and after initial key establishment should 00640 * be kept as private information. There are a lot of ways to create 00641 * insecure keys, the most notable is to simply take a password as the key 00642 * without processing the password further. A simple and secure way to 00643 * create a key for a particular Cipher is 00644 * 00645 * cipher = OpenSSL::AES256.new(:CFB) 00646 * cipher.encrypt 00647 * key = cipher.random_key # also sets the generated key on the Cipher 00648 * 00649 * If you absolutely need to use passwords as encryption keys, you 00650 * should use Password-Based Key Derivation Function 2 (PBKDF2) by 00651 * generating the key with the help of the functionality provided by 00652 * OpenSSL::PKCS5.pbkdf2_hmac_sha1 or OpenSSL::PKCS5.pbkdf2_hmac. 00653 * 00654 * Although there is Cipher#pkcs5_keyivgen, its use is deprecated and 00655 * it should only be used in legacy applications because it does not use 00656 * the newer PKCS#5 v2 algorithms. 00657 * 00658 * === Choosing an IV 00659 * 00660 * The cipher modes CBC, CFB, OFB and CTR all need an "initialization 00661 * vector", or short, IV. ECB mode is the only mode that does not require 00662 * an IV, but there is almost no legitimate use case for this mode 00663 * because of the fact that it does not sufficiently hide plaintext 00664 * patterns. Therefore 00665 * 00666 * <b>You should never use ECB mode unless you are absolutely sure that 00667 * you absolutely need it</b> 00668 * 00669 * Because of this, you will end up with a mode that explicitly requires 00670 * an IV in any case. Note that for backwards compatibility reasons, 00671 * setting an IV is not explicitly mandated by the Cipher API. If not 00672 * set, OpenSSL itself defaults to an all-zeroes IV ("\\0", not the 00673 * character). Although the IV can be seen as public information, i.e. 00674 * it may be transmitted in public once generated, it should still stay 00675 * unpredictable to prevent certain kinds of attacks. Therefore, ideally 00676 * 00677 * <b>Always create a secure random IV for every encryption of your 00678 * Cipher</b> 00679 * 00680 * A new, random IV should be created for every encryption of data. Think 00681 * of the IV as a nonce (number used once) - it's public but random and 00682 * unpredictable. A secure random IV can be created as follows 00683 * 00684 * cipher = ... 00685 * cipher.encrypt 00686 * key = cipher.random_key 00687 * iv = cipher.random_iv # also sets the generated IV on the Cipher 00688 * 00689 * Although the key is generally a random value, too, it is a bad choice 00690 * as an IV. There are elaborate ways how an attacker can take advantage 00691 * of such an IV. As a general rule of thumb, exposing the key directly 00692 * or indirectly should be avoided at all cost and exceptions only be 00693 * made with good reason. 00694 * 00695 * === Calling Cipher#final 00696 * 00697 * ECB (which should not be used) and CBC are both block-based modes. 00698 * This means that unlike for the other streaming-based modes, they 00699 * operate on fixed-size blocks of data, and therefore they require a 00700 * "finalization" step to produce or correctly decrypt the last block of 00701 * data by appropriately handling some form of padding. Therefore it is 00702 * essential to add the output of OpenSSL::Cipher#final to your 00703 * encryption/decryption buffer or you will end up with decryption errors 00704 * or truncated data. 00705 * 00706 * Although this is not really necessary for streaming-mode ciphers, it is 00707 * still recommended to apply the same pattern of adding the output of 00708 * Cipher#final there as well - it also enables you to switch between 00709 * modes more easily in the future. 00710 * 00711 * === Encrypting and decrypting some data 00712 * 00713 * data = "Very, very confidential data" 00714 * 00715 * cipher = OpenSSL::Cipher::AES.new(128, :CBC) 00716 * cipher.encrypt 00717 * key = cipher.random_key 00718 * iv = cipher.random_iv 00719 * 00720 * encrypted = cipher.update(data) + cipher.final 00721 * ... 00722 * decipher = OpenSSL::Cipher::AES.new(128, :CBC) 00723 * decipher.decrypt 00724 * decipher.key = key 00725 * decipher.iv = iv 00726 * 00727 * plain = decipher.update(encrypted) + decipher.final 00728 * 00729 * puts data == plain #=> true 00730 * 00731 */ 00732 cCipher = rb_define_class_under(mOSSL, "Cipher", rb_cObject); 00733 eCipherError = rb_define_class_under(cCipher, "CipherError", eOSSLError); 00734 00735 rb_define_alloc_func(cCipher, ossl_cipher_alloc); 00736 rb_define_copy_func(cCipher, ossl_cipher_copy); 00737 rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0); 00738 rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1); 00739 rb_define_method(cCipher, "reset", ossl_cipher_reset, 0); 00740 rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1); 00741 rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1); 00742 rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1); 00743 rb_define_method(cCipher, "update", ossl_cipher_update, -1); 00744 rb_define_method(cCipher, "final", ossl_cipher_final, 0); 00745 rb_define_method(cCipher, "name", ossl_cipher_name, 0); 00746 rb_define_method(cCipher, "key=", ossl_cipher_set_key, 1); 00747 rb_define_method(cCipher, "key_len=", ossl_cipher_set_key_length, 1); 00748 rb_define_method(cCipher, "key_len", ossl_cipher_key_length, 0); 00749 rb_define_method(cCipher, "iv=", ossl_cipher_set_iv, 1); 00750 rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0); 00751 rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0); 00752 rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1); 00753 } 00754 00755