class SSHKey

Constants

SSH_CONVERSION
SSH_TYPES
VERSION

Attributes

comment[RW]
directives[R]
key_object[R]
passphrase[RW]
type[R]

Public Class Methods

fingerprint(key) click to toggle source
Alias for: md5_fingerprint
generate(options = {}) click to toggle source

Generate a new keypair and return an SSHKey object

The default behavior when providing no options will generate a 2048-bit RSA keypair.

Parameters

  • options<~Hash>:

    • :type<~String> - "rsa" or "dsa", "rsa" by default

    • :bits<~Integer> - Bit length

    • :comment<~String> - Comment to use for the public key, defaults to ""

    • :passphrase<~String> - Encrypt the key with this passphrase

# File lib/sshkey.rb, line 26
def generate(options = {})
  type   = options[:type] || "rsa"

  # JRuby modulus size must range from 512 to 1024
  default_bits = type == "rsa" ? 2048 : 1024

  bits   = options[:bits] || default_bits
  cipher = OpenSSL::Cipher::Cipher.new("AES-128-CBC") if options[:passphrase]

  case type.downcase
  when "rsa" then new(OpenSSL::PKey::RSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
  when "dsa" then new(OpenSSL::PKey::DSA.generate(bits).to_pem(cipher, options[:passphrase]), options)
  else
    raise "Unknown key type: #{type}"
  end
end
md5_fingerprint(key) click to toggle source

Fingerprints

Accepts either a public or private key

MD5 fingerprint for the given SSH key

# File lib/sshkey.rb, line 73
def md5_fingerprint(key)
  if key.match(%rPRIVATE/)
    new(key).md5_fingerprint
  else
    Digest::MD5.hexdigest(decoded_key(key)).gsub(fingerprint_regex, '\1:\2')
  end
end
Also aliased as: fingerprint
new(private_key, options = {}) click to toggle source

Create a new SSHKey object

Parameters

  • #private_key - Existing RSA or DSA private key

  • options<~Hash>

    • :comment<~String> - Comment to use for the public key, defaults to ""

    • :passphrase<~String> - If the key is encrypted, supply the passphrase

    • :directives<~Array> - Options prefixed to the public key

# File lib/sshkey.rb, line 153
def initialize(private_key, options = {})
  @passphrase = options[:passphrase]
  @comment    = options[:comment] || ""
  self.directives = options[:directives] || []
  begin
    @key_object = OpenSSL::PKey::RSA.new(private_key, passphrase)
    @type = "rsa"
  rescue
    @key_object = OpenSSL::PKey::DSA.new(private_key, passphrase)
    @type = "dsa"
  end
end
sha1_fingerprint(key) click to toggle source

SHA1 fingerprint for the given SSH key

# File lib/sshkey.rb, line 83
def sha1_fingerprint(key)
  if key.match(%rPRIVATE/)
    new(key).sha1_fingerprint
  else
    Digest::SHA1.hexdigest(decoded_key(key)).gsub(fingerprint_regex, '\1:\2')
  end
end
ssh_public_key_bits(ssh_public_key) click to toggle source

Bits

Returns ssh public key bits or false depending on the validity of the public key provided

Parameters

# File lib/sshkey.rb, line 64
def ssh_public_key_bits(ssh_public_key)
  unpacked_byte_array( *parse_ssh_public_key(ssh_public_key) ).last.size * 8
end
valid_ssh_public_key?(ssh_public_key) click to toggle source

Validate an existing SSH public key

Returns true or false depending on the validity of the public key provided

Parameters

# File lib/sshkey.rb, line 50
def valid_ssh_public_key?(ssh_public_key)
  ssh_type, encoded_key = parse_ssh_public_key(ssh_public_key)
  SSH_CONVERSION[SSH_TYPES.invert[ssh_type]].size == unpacked_byte_array(ssh_type, encoded_key).size
rescue
  false
end

Public Instance Methods

bits() click to toggle source

Determine the length (bits) of the key as an integer

# File lib/sshkey.rb, line 211
def bits
  self.class.ssh_public_key_bits(ssh_public_key)
end
directives=(directives) click to toggle source
# File lib/sshkey.rb, line 272
def directives=(directives)
  @directives = Array[directives].flatten.compact
end
dsa_private_key() click to toggle source
Alias for: private_key
dsa_public_key() click to toggle source
Alias for: public_key
encrypted_private_key() click to toggle source

Fetch the encrypted RSA/DSA private key using the passphrase provided

If no passphrase is set, returns the unencrypted private key

# File lib/sshkey.rb, line 178
def encrypted_private_key
  return private_key unless passphrase
  key_object.to_pem(OpenSSL::Cipher::Cipher.new("AES-128-CBC"), passphrase)
end
fingerprint() click to toggle source
Alias for: md5_fingerprint
md5_fingerprint() click to toggle source

Fingerprints

MD5 fingerprint for the given SSH public key

# File lib/sshkey.rb, line 200
def md5_fingerprint
  Digest::MD5.hexdigest(ssh_public_key_conversion).gsub(%r(.{2})(?=.)/, '\1:\2')
end
Also aliased as: fingerprint
private_key() click to toggle source

Fetch the RSA/DSA private key

#rsa_private_key and #dsa_private_key are aliased for backward compatibility

# File lib/sshkey.rb, line 169
def private_key
  key_object.to_pem
end
Also aliased as: rsa_private_key, dsa_private_key
public_key() click to toggle source

Fetch the RSA/DSA public key

#rsa_public_key and #dsa_public_key are aliased for backward compatibility

# File lib/sshkey.rb, line 186
def public_key
  key_object.public_key.to_pem
end
Also aliased as: rsa_public_key, dsa_public_key
randomart() click to toggle source

Randomart

Generate OpenSSH compatible ASCII art fingerprints See www.opensource.apple.com/source/OpenSSH/OpenSSH-175/openssh/key.c (key_fingerprint_randomart function)

Example: +--[ RSA 2048]----+ |o+ o.. | |..+.o | | ooo | |.++. o | |o + S | |.. + o . | | . + . | | . . | | Eo. | -----------------

# File lib/sshkey.rb, line 232
def randomart
  fieldsize_x = 17
  fieldsize_y = 9
  x = fieldsize_x / 2
  y = fieldsize_y / 2
  raw_digest = Digest::MD5.digest(ssh_public_key_conversion)
  num_bytes = raw_digest.bytesize

  field = Array.new(fieldsize_x) { Array.new(fieldsize_y) {0} }

  raw_digest.bytes.each do |byte|
    4.times do
      x += (byte & 0x1 != 0) ? 1 : -1
      y += (byte & 0x2 != 0) ? 1 : -1

      x = [[x, 0].max, fieldsize_x - 1].min
      y = [[y, 0].max, fieldsize_y - 1].min

      field[x][y] += 1 if (field[x][y] < num_bytes - 2)

      byte >>= 2
    end
  end

  field[fieldsize_x / 2][fieldsize_y / 2] = num_bytes - 1
  field[x][y] = num_bytes
  augmentation_string = " .o+=*BOX@%&#/^SE"
  output = "+--#{sprintf("[%4s %4u]", type.upcase, bits)}----+\n"
  fieldsize_y.times do |y|
    output << "|"
    fieldsize_x.times do |x|
      output << augmentation_string[[field[x][y], num_bytes].min]
    end
    output << "|"
    output << "\n"
  end
  output << "+#{"-" * fieldsize_x}+"
  output
end
rsa_private_key() click to toggle source
Alias for: private_key
rsa_public_key() click to toggle source
Alias for: public_key
sha1_fingerprint() click to toggle source

SHA1 fingerprint for the given SSH public key

# File lib/sshkey.rb, line 206
def sha1_fingerprint
  Digest::SHA1.hexdigest(ssh_public_key_conversion).gsub(%r(.{2})(?=.)/, '\1:\2')
end
ssh_public_key() click to toggle source

SSH public key

# File lib/sshkey.rb, line 193
def ssh_public_key
  [directives.join(",").strip, SSH_TYPES[type], Base64.encode64(ssh_public_key_conversion).gsub("\n", ""), comment].join(" ").strip
end