Class: RSA::KeyPair

Inherits:
Object
  • Object
show all
Defined in:
lib/rsa/openssl.rb,
lib/rsa/key_pair.rb

Overview

An RSA key pair.

Refer to PKCS #1 v2.1, section 3, pp. 6-8.

See Also:

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (KeyPair) initialize(private_key, public_key, options = {})

Initializes a new key pair.

Parameters:

  • (Key) private_key
  • (Key) public_key
  • (Hash{Symbol => Object}) options (defaults to: {})


30
31
32
33
34
# File 'lib/rsa/key_pair.rb', line 30

def initialize(private_key, public_key, options = {})
  @private_key = private_key
  @public_key  = public_key
  @options     = options.dup
end

Instance Attribute Details

- (Key) private_key (readonly) Also known as: private

The RSA private key.

Returns:



14
15
16
# File 'lib/rsa/key_pair.rb', line 14

def private_key
  @private_key
end

- (Key) public_key (readonly) Also known as: public

The RSA public key.

Returns:



21
22
23
# File 'lib/rsa/key_pair.rb', line 21

def public_key
  @public_key
end

Class Method Details

+ (KeyPair) generate(bits, exponent = 65537)

Generates a new RSA key pair of length bits.

By default, the public exponent will be 65537 (0x10001) as recommended by PKCS #1.

Parameters:

  • (Integer, #to_i) bits
  • (Integer, #to_i) exponent (defaults to: 65537)

Returns:



16
17
18
19
20
# File 'lib/rsa/openssl.rb', line 16

def self.generate(bits, exponent = 65537)
  pkey = ::OpenSSL::PKey::RSA.generate(bits.to_i, exponent.to_i)
  n, d, e = pkey.n.to_i, pkey.d.to_i, pkey.e.to_i
  self.new(Key.new(n, d), Key.new(n, e))
end

Instance Method Details

- (Integer) bitsize Also known as: size

Returns the bit size of this key pair.

Returns:

  • (Integer)


76
77
78
# File 'lib/rsa/key_pair.rb', line 76

def bitsize
  Math.log2(modulus).ceil
end

- (Integer) bytesize

Returns the byte size of this key pair.

Returns:

  • (Integer)


68
69
70
# File 'lib/rsa/key_pair.rb', line 68

def bytesize
  Math.log256(modulus).ceil
end

- (Integer) decrypt(ciphertext, options = {}) - (String) decrypt(ciphertext, options = {})

Decrypts the given ciphertext using the private key from this key pair.

Overloads:

  • - (Integer) decrypt(ciphertext, options = {})

    Parameters:

    • (Integer) ciphertext
    • (Hash{Symbol => Object}) options

    Returns:

    • (Integer)
  • - (String) decrypt(ciphertext, options = {})

    Parameters:

    • (String, IO, StringIO) ciphertext
    • (Hash{Symbol => Object}) options

    Returns:

    • (String)

Parameters:

  • (Object) ciphertext
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (Symbol, #to_sym) :padding — default: nil


144
145
146
147
148
149
150
151
# File 'lib/rsa/key_pair.rb', line 144

def decrypt(ciphertext, options = {})
  case ciphertext
    when Integer      then decrypt_integer(ciphertext, options)
    when String       then PKCS1.i2osp(decrypt_integer(PKCS1.os2ip(ciphertext), options))
    when StringIO, IO then PKCS1.i2osp(decrypt_integer(PKCS1.os2ip(ciphertext.read), options))
    else raise ArgumentError, ciphertext.inspect # FIXME
  end
end

- (Integer) encrypt(plaintext, options = {}) - (String) encrypt(plaintext, options = {})

Encrypts the given plaintext using the public key from this key pair.

Overloads:

  • - (Integer) encrypt(plaintext, options = {})

    Parameters:

    • (Integer) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (Integer)
  • - (String) encrypt(plaintext, options = {})

    Parameters:

    • (String, IO, StringIO) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (String)

Parameters:

  • (Object) plaintext
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (Symbol, #to_sym) :padding — default: nil


118
119
120
121
122
123
124
125
# File 'lib/rsa/key_pair.rb', line 118

def encrypt(plaintext, options = {})
  case plaintext
    when Integer      then encrypt_integer(plaintext, options)
    when String       then PKCS1.i2osp(encrypt_integer(PKCS1.os2ip(plaintext), options))
    when StringIO, IO then PKCS1.i2osp(encrypt_integer(PKCS1.os2ip(plaintext.read), options))
    else raise ArgumentError, plaintext.inspect # FIXME
  end
end

- (Integer) modulus Also known as: n

Returns the RSA modulus for this key pair.

Returns:

  • (Integer)


85
86
87
# File 'lib/rsa/key_pair.rb', line 85

def modulus
  private_key ? private_key.modulus : public_key.modulus
end

- (Boolean) private_key? Also known as: private?

Returns true if this key pair contains a private key.

Returns:

  • (Boolean)


40
41
42
# File 'lib/rsa/key_pair.rb', line 40

def private_key?
  !!private_key
end

- (Boolean) public_key? Also known as: public?

Returns true if this key pair contains a public key.

Returns:

  • (Boolean)


49
50
51
# File 'lib/rsa/key_pair.rb', line 49

def public_key?
  !!public_key
end

- (Integer) sign(plaintext, options = {}) - (String) sign(plaintext, options = {})

Signs the given plaintext using the private key from this key pair.

Overloads:

  • - (Integer) sign(plaintext, options = {})

    Parameters:

    • (Integer) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (Integer)
  • - (String) sign(plaintext, options = {})

    Parameters:

    • (String, IO, StringIO) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (String)

Parameters:

  • (Object) plaintext
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (Symbol, #to_sym) :padding — default: nil


169
170
171
172
173
174
175
176
# File 'lib/rsa/key_pair.rb', line 169

def sign(plaintext, options = {})
  case plaintext
    when Integer      then sign_integer(plaintext, options)
    when String       then PKCS1.i2osp(sign_integer(PKCS1.os2ip(plaintext), options))
    when StringIO, IO then PKCS1.i2osp(sign_integer(PKCS1.os2ip(plaintext.read), options))
    else raise ArgumentError, plaintext.inspect # FIXME
  end
end

- (Hash) to_hash

Returns a hash table representation of this key pair.

Examples:

key_pair.to_hash  #=> {:n => ..., :d => ..., :e => ...}

Returns:

  • (Hash)


97
98
99
# File 'lib/rsa/key_pair.rb', line 97

def to_hash
  {:n => modulus, :d => private_key ? private_key.exponent : nil, :e => public_key ? public_key.exponent : nil}
end

- (OpenSSL::PKey::RSA) to_openssl

Returns this key pair as an OpenSSL::PKey::RSA instance.

Returns:

  • (OpenSSL::PKey::RSA)


26
27
28
29
30
31
32
33
34
35
# File 'lib/rsa/openssl.rb', line 26

def to_openssl
  @openssl_pkey ||= begin
    pkey   = ::OpenSSL::PKey::RSA.new
    pkey.n = private_key.modulus  if private_key?
    pkey.e = private_key.exponent if private_key?
    pkey.n ||= public_key.modulus if public_key?
    pkey.d = public_key.exponent  if public_key?
    pkey
  end
end

- (Boolean) valid?

Returns true if this is a valid RSA key pair according to PKCS #1.

Returns:

  • (Boolean)

See Also:



60
61
62
# File 'lib/rsa/key_pair.rb', line 60

def valid?
  private_key.valid? && public_key.valid?
end

- (Boolean) verify(signature, plaintext, options = {}) - (Boolean) verify(signature, plaintext, options = {})

Verifies the given signature using the public key from this key pair.

Overloads:

  • - (Boolean) verify(signature, plaintext, options = {})

    Parameters:

    • (Integer) signature
    • (Integer) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (Boolean)
  • - (Boolean) verify(signature, plaintext, options = {})

    Parameters:

    • (String, IO, StringIO) signature
    • (String, IO, StringIO) plaintext
    • (Hash{Symbol => Object}) options

    Returns:

    • (Boolean)

Parameters:

  • (Object) signature
  • (Object) plaintext
  • (Hash{Symbol => Object}) options (defaults to: {})

Options Hash (options):

  • (Symbol, #to_sym) :padding — default: nil

Returns:

  • (Boolean)


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/rsa/key_pair.rb', line 199

def verify(signature, plaintext, options = {})
  signature = case signature
    when Integer      then signature
    when String       then PKCS1.os2ip(signature)
    when StringIO, IO then PKCS1.os2ip(signature.read)
    else raise ArgumentError, signature.inspect # FIXME
  end
  plaintext = case plaintext
    when Integer      then plaintext
    when String       then PKCS1.os2ip(plaintext)
    when StringIO, IO then PKCS1.os2ip(plaintext.read)
    else raise ArgumentError, plaintext.inspect # FIXME
  end
  verify_integer(signature, plaintext, options)
end