Class: OpenSSL::Cipher

Inherits:
Object
  • Object
show all
Defined in:
lib/openssl/cipher.rb,
ext/rubysl/openssl/ossl_cipher.c

Direct Known Subclasses

Cipher

Defined Under Namespace

Classes: Cipher, CipherError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new(string) ⇒ Object

The string must contain a valid cipher name like “AES-128-CBC” or “3DES”.

A list of cipher names is available by calling OpenSSL::Cipher.ciphers.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'ext/rubysl/openssl/ossl_cipher.c', line 94

static VALUE
ossl_cipher_initialize(VALUE self, VALUE str)
{
    EVP_CIPHER_CTX *ctx;
    const EVP_CIPHER *cipher;
    char *name;

    name = StringValuePtr(str);
    GetCipher(self, ctx);
    if (!(cipher = EVP_get_cipherbyname(name))) {
	ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name);
    }
    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
	ossl_raise(eCipherError, NULL);

    return self;
}

Class Method Details

.ciphersObject

Returns the names of all available ciphers in an array.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'ext/rubysl/openssl/ossl_cipher.c', line 142

static VALUE
ossl_s_ciphers(VALUE self)
{
#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED
    VALUE ary;

    ary = rb_ary_new();
    OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
                    (void(*)(const OBJ_NAME*,void*))add_cipher_name_to_ary,
                    (void*)ary);

    return ary;
#else
    rb_notimplement();
#endif
}

Instance Method Details

#<<(data) ⇒ String

Parameters

data is a nonempty string.

This method is deprecated and not available in 1.9.x or later.

Returns:

  • (String)


309
310
311
312
313
314
315
316
317
# File 'ext/rubysl/openssl/ossl_cipher.c', line 309

static VALUE
ossl_cipher_update_deprecated(VALUE self, VALUE data)
{
    const char *cname;

    cname = rb_class2name(rb_obj_class(self));
    rb_warning("%s#<< is deprecated; use %s#update instead", cname, cname);
    return rb_funcall(self, rb_intern("update"), 1, data);
}

#block_sizeInteger

Returns:



532
# File 'ext/rubysl/openssl/ossl_cipher.c', line 532

static VALUE ossl_cipher_block_size() { }

#decryptself

Make sure to call .encrypt or .decrypt before using any of the following methods:

  • key=, iv=, random_key, random_iv, pkcs5_keyivgen

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).

Returns:

  • (self)


245
246
247
248
249
# File 'ext/rubysl/openssl/ossl_cipher.c', line 245

static VALUE
ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
{
    return ossl_cipher_init(argc, argv, self, 0);
}

#encryptself

Make sure to call .encrypt or .decrypt before using any of the following methods:

  • key=, iv=, random_key, random_iv, pkcs5_keyivgen

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).

Returns:

  • (self)


230
231
232
233
234
# File 'ext/rubysl/openssl/ossl_cipher.c', line 230

static VALUE
ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
{
    return ossl_cipher_init(argc, argv, self, 1);
}

#finalaString

Returns the remaining data held in the cipher object. Further calls to update() or final() will return garbage.

See EVP_CipherFinal_ex for further information.

Returns:

  • (aString)


368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'ext/rubysl/openssl/ossl_cipher.c', line 368

static VALUE 
ossl_cipher_final(VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    int out_len;
    VALUE str;

    GetCipher(self, ctx);
    str = rb_str_new(0, EVP_CIPHER_CTX_block_size(ctx));
    if (!EVP_CipherFinal_ex(ctx, RSTRING_PTR(str), &out_len))
	ossl_raise(eCipherError, NULL);
    assert(out_len <= RSTRING_LEN(str));
    rb_str_set_len(str, out_len);

    return str;
}

#iv=(string) ⇒ String

Sets the cipher iv.

Only call this method after calling cipher.encrypt or cipher.decrypt.

Returns:

  • (String)


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# File 'ext/rubysl/openssl/ossl_cipher.c', line 434

static VALUE
ossl_cipher_set_iv(VALUE self, VALUE iv)
{
    EVP_CIPHER_CTX *ctx;

    StringValue(iv);
    GetCipher(self, ctx);

    if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))
        ossl_raise(eCipherError, "iv length too short");

    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, RSTRING_PTR(iv), -1) != 1)
	ossl_raise(eCipherError, NULL);

    return iv;
}

#iv_lengthInteger

Returns:



526
# File 'ext/rubysl/openssl/ossl_cipher.c', line 526

static VALUE ossl_cipher_iv_length() { }

#key=(string) ⇒ String

Sets the cipher key.

Only call this method after calling cipher.encrypt or cipher.decrypt.

Returns:

  • (String)


409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
# File 'ext/rubysl/openssl/ossl_cipher.c', line 409

static VALUE
ossl_cipher_set_key(VALUE self, VALUE key)
{
    EVP_CIPHER_CTX *ctx;

    StringValue(key);
    GetCipher(self, ctx);

    if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))
        ossl_raise(eCipherError, "key length too short");

    if (EVP_CipherInit_ex(ctx, NULL, NULL, RSTRING_PTR(key), NULL, -1) != 1)
        ossl_raise(eCipherError, NULL);

    return key;
}

#key_lenObject

#key_length=(integer) ⇒ Integer

Sets the key length of the cipher. If the cipher is a fixed length cipher then attempting to set the key length to any value other than the fixed value is an error.

Under normal circumstances you do not need to call this method (and probably shouldn’t).

See EVP_CIPHER_CTX_set_key_length for further information.

Returns:



463
464
465
466
467
468
469
470
471
472
473
474
# File 'ext/rubysl/openssl/ossl_cipher.c', line 463

static VALUE
ossl_cipher_set_key_length(VALUE self, VALUE key_length)
{
    int len = NUM2INT(key_length);
    EVP_CIPHER_CTX *ctx;
 
    GetCipher(self, ctx);
    if (EVP_CIPHER_CTX_set_key_length(ctx, len) != 1)
        ossl_raise(eCipherError, NULL);

    return key_length;
}

#nameString

Returns the name of the cipher which may differ slightly from the original name provided.

Returns:

  • (String)


391
392
393
394
395
396
397
398
399
# File 'ext/rubysl/openssl/ossl_cipher.c', line 391

static VALUE
ossl_cipher_name(VALUE self)
{
    EVP_CIPHER_CTX *ctx;

    GetCipher(self, ctx);

    return rb_str_new2(EVP_CIPHER_name(EVP_CIPHER_CTX_cipher(ctx)));
}

#padding=(integer) ⇒ Integer

Enables or disables padding. By default encryption operations are padded using standard block padding and the padding is checked and removed when decrypting. If the pad parameter is zero then no padding is performed, the total amount of data encrypted or decrypted must then be a multiple of the block size or an error will occur.

See EVP_CIPHER_CTX_set_padding for further information.

Returns:



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
# File 'ext/rubysl/openssl/ossl_cipher.c', line 486

static VALUE
ossl_cipher_set_padding(VALUE self, VALUE padding)
{
#if defined(HAVE_EVP_CIPHER_CTX_SET_PADDING)
    EVP_CIPHER_CTX *ctx;
    int pad = NUM2INT(padding);

    GetCipher(self, ctx);
    if (EVP_CIPHER_CTX_set_padding(ctx, pad) != 1)
	ossl_raise(eCipherError, NULL);
#else
    rb_notimplement();
#endif
    return padding;
}

#pkcs5_keyivgen(pass[, salt [, iterations [, digest]]]) ⇒ nil

Generates and sets the key/iv based on a password.

WARNING: This method is only PKCS5 v1.5 compliant when using RC2, RC4-40, or DES with MD5 or SHA1. Using anything else (like AES) will generate the key/iv using an OpenSSL specific method. Use a PKCS5 v2 key generation method instead.

Parameters

salt must be an 8 byte string if provided. iterations is a integer with a default of 2048. digest is a Digest object that defaults to ‘MD5’

A minimum of 1000 iterations is recommended.

Returns:

  • (nil)


269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'ext/rubysl/openssl/ossl_cipher.c', line 269

static VALUE
ossl_cipher_pkcs5_keyivgen(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    const EVP_MD *digest;
    VALUE vpass, vsalt, viter, vdigest;
    unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH], *salt = NULL;
    int iter;

    rb_scan_args(argc, argv, "13", &vpass, &vsalt, &viter, &vdigest);
    StringValue(vpass);
    if(!NIL_P(vsalt)){
	StringValue(vsalt);
	if(RSTRING_LEN(vsalt) != PKCS5_SALT_LEN)
	    rb_raise(eCipherError, "salt must be an 8-octet string");
	salt = RSTRING_PTR(vsalt);
    }
    iter = NIL_P(viter) ? 2048 : NUM2INT(viter);
    digest = NIL_P(vdigest) ? EVP_md5() : GetDigestPtr(vdigest);
    GetCipher(self, ctx);
    EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), digest, salt,
		   RSTRING_PTR(vpass), RSTRING_LEN(vpass), iter, key, iv); 
    if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, -1) != 1)
	ossl_raise(eCipherError, NULL);
    OPENSSL_cleanse(key, sizeof key);
    OPENSSL_cleanse(iv, sizeof iv);

    return Qnil;
}

#random_ivObject

Generate, set, and return a random iv. You must call cipher.encrypt or cipher.decrypt before calling this method.



54
55
56
57
58
# File 'lib/openssl/cipher.rb', line 54

def random_iv
  str = OpenSSL::Random.random_bytes(self.iv_len)
  self.iv = str
  return str
end

#random_keyObject

Generate, set, and return a random key. You must call cipher.encrypt or cipher.decrypt before calling this method.



46
47
48
49
50
# File 'lib/openssl/cipher.rb', line 46

def random_key
  str = OpenSSL::Random.random_bytes(self.key_len)
  self.key = str
  return str
end

#resetself

Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1).

Returns:

  • (self)


165
166
167
168
169
170
171
172
173
174
175
# File 'ext/rubysl/openssl/ossl_cipher.c', line 165

static VALUE
ossl_cipher_reset(VALUE self)
{
    EVP_CIPHER_CTX *ctx;

    GetCipher(self, ctx);
    if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, -1) != 1)
	ossl_raise(eCipherError, NULL);
		
    return self;
}

#update(data[, buffer]) ⇒ String

Parameters

data is a nonempty string. buffer is an optional string to store the result.

Returns:

  • (String)


328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'ext/rubysl/openssl/ossl_cipher.c', line 328

static VALUE 
ossl_cipher_update(int argc, VALUE *argv, VALUE self)
{
    EVP_CIPHER_CTX *ctx;
    char *in;
    int in_len, out_len;
    VALUE data, str;

    rb_scan_args(argc, argv, "11", &data, &str);

    StringValue(data);
    in = RSTRING_PTR(data);
    if ((in_len = RSTRING_LEN(data)) == 0)
        rb_raise(rb_eArgError, "data must not be empty");
    GetCipher(self, ctx);
    out_len = in_len+EVP_CIPHER_CTX_block_size(ctx);

    if (NIL_P(str)) {
        str = rb_str_new(0, out_len);
    } else {
        StringValue(str);
        rb_str_resize(str, out_len);
    }

    if (!EVP_CipherUpdate(ctx, RSTRING_PTR(str), &out_len, in, in_len))
	ossl_raise(eCipherError, NULL);
    assert(out_len < RSTRING_LEN(str));
    rb_str_set_len(str, out_len);

    return str;
}