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.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(private_key, public_key, options = {}) ⇒ KeyPair

Initializes a new key pair.

Parameters:

  • private_key (Key)
  • public_key (Key)
  • options (Hash{Symbol => Object}) (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

#private_keyKey (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

#public_keyKey (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

.generate(bits, exponent = 65537) ⇒ KeyPair

Generates a new RSA key pair of length ‘bits`.

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

Parameters:

  • bits (Integer, #to_i)
  • exponent (Integer, #to_i) (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

#bitsizeInteger 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

#bytesizeInteger

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

#decrypt(ciphertext, options = {}) ⇒ Integer #decrypt(ciphertext, options = {}) ⇒ String

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

Overloads:

  • #decrypt(ciphertext, options = {}) ⇒ Integer

    Parameters:

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

    Returns:

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

    Parameters:

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

    Returns:

    • (String)

Parameters:

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

Options Hash (options):

  • :padding (Symbol, #to_sym) — 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

#encrypt(plaintext, options = {}) ⇒ Integer #encrypt(plaintext, options = {}) ⇒ String

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

Overloads:

  • #encrypt(plaintext, options = {}) ⇒ Integer

    Parameters:

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

    Returns:

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

    Parameters:

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

    Returns:

    • (String)

Parameters:

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

Options Hash (options):

  • :padding (Symbol, #to_sym) — 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

#modulusInteger 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

#private_key?Boolean 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

#public_key?Boolean 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

#sign(plaintext, options = {}) ⇒ Integer #sign(plaintext, options = {}) ⇒ String

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

Overloads:

  • #sign(plaintext, options = {}) ⇒ Integer

    Parameters:

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

    Returns:

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

    Parameters:

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

    Returns:

    • (String)

Parameters:

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

Options Hash (options):

  • :padding (Symbol, #to_sym) — 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

#to_hashHash

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

#to_opensslOpenSSL::PKey::RSA

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

#valid?Boolean

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

#verify(signature, plaintext, options = {}) ⇒ Boolean #verify(signature, plaintext, options = {}) ⇒ Boolean

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

Overloads:

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

    Parameters:

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

    Returns:

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

    Parameters:

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

    Returns:

    • (Boolean)

Parameters:

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

Options Hash (options):

  • :padding (Symbol, #to_sym) — 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