sshkey 1.1.3 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +67 -0
- data/lib/sshkey.rb +84 -15
- data/lib/sshkey/version.rb +1 -1
- data/test/sshkey_test.rb +60 -2
- metadata +3 -3
- data/README.rdoc +0 -48
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
sshkey
|
2
|
+
======
|
3
|
+
|
4
|
+
Generate private/public SSH keys using Ruby without the `ssh-keygen` system command.
|
5
|
+
|
6
|
+
gem install sshkey
|
7
|
+
|
8
|
+
Tested on the following Rubies: MRI 1.8.7 and 1.9.2, Rubinius, JRuby. Ruby must be compiled with OpenSSL support.
|
9
|
+
|
10
|
+
Usage
|
11
|
+
-----
|
12
|
+
|
13
|
+
Generate an SSH RSA Keypair with foo@bar.com as the comment - providing a comment is optional
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
k = SSHKey.generate(:comment => "foo@bar.com")
|
17
|
+
```
|
18
|
+
|
19
|
+
Generate an SSH DSA Keypair with foo@bar.com as the comment - providing a comment is optional
|
20
|
+
|
21
|
+
``` ruby
|
22
|
+
k = SSHKey.generate(:type => "dsa", :comment => "foo@bar.com")
|
23
|
+
```
|
24
|
+
|
25
|
+
Return an SSHKey object from an existing RSA Private Key (provided as a string)
|
26
|
+
|
27
|
+
``` ruby
|
28
|
+
k = SSHKey.new(File.read("~/.ssh/id_rsa"), :comment => "foo@bar.com")
|
29
|
+
```
|
30
|
+
|
31
|
+
Both of these will return an SSHKey object with the following methods:
|
32
|
+
|
33
|
+
``` ruby
|
34
|
+
# Returns an OpenSSL::PKey::RSA or OpenSSL::PKey::DSA key object
|
35
|
+
# See http://www.ruby-doc.org/stdlib/libdoc/openssl/rdoc/classes/OpenSSL/PKey/RSA.html
|
36
|
+
k.key_object
|
37
|
+
# => -----BEGIN RSA PRIVATE KEY-----\nMIIEowI...
|
38
|
+
|
39
|
+
# Returns the Private Key as a string
|
40
|
+
k.private_key
|
41
|
+
# => "-----BEGIN RSA PRIVATE KEY-----\nMIIEowI..."
|
42
|
+
|
43
|
+
# Returns the Public Key as a string
|
44
|
+
k.public_key
|
45
|
+
# => "-----BEGIN RSA PUBLIC KEY-----\nMIIBCg..."
|
46
|
+
|
47
|
+
# Returns the SSH Public Key as a string
|
48
|
+
k.ssh_public_key
|
49
|
+
# => "ssh-rsa AAAAB3NzaC1yc2EA...."
|
50
|
+
|
51
|
+
# Returns the comment as a string
|
52
|
+
k.comment
|
53
|
+
# => "foo@bar.com"
|
54
|
+
|
55
|
+
# Returns the fingerprint as a string
|
56
|
+
k.fingerprint
|
57
|
+
# => "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
58
|
+
|
59
|
+
# Validates SSH Public Key
|
60
|
+
SSHKey.valid? "ssh-rsa AAAAB3NzaC1yc2EA...."
|
61
|
+
# => true
|
62
|
+
```
|
63
|
+
|
64
|
+
Copyright
|
65
|
+
---------
|
66
|
+
|
67
|
+
Copyright (c) 2011 James Miller
|
data/lib/sshkey.rb
CHANGED
@@ -3,28 +3,97 @@ require 'base64'
|
|
3
3
|
require 'digest/md5'
|
4
4
|
|
5
5
|
class SSHKey
|
6
|
+
SSH_TYPES = {"rsa" => "ssh-rsa", "dsa" => "ssh-dss"}
|
7
|
+
SSH_CONVERSION = {"rsa" => ["e", "n"], "dsa" => ["p", "q", "g", "pub_key"]}
|
8
|
+
|
9
|
+
attr_reader :key_object, :comment, :type
|
6
10
|
|
7
11
|
def self.generate(options = {})
|
8
|
-
|
12
|
+
type = options[:type] || "rsa"
|
13
|
+
case type
|
14
|
+
when "rsa" then SSHKey.new(OpenSSL::PKey::RSA.generate(2048).to_pem, options)
|
15
|
+
when "dsa" then SSHKey.new(OpenSSL::PKey::DSA.generate(2048).to_pem, options)
|
16
|
+
else
|
17
|
+
raise "Unknown key type #{type}"
|
18
|
+
end
|
9
19
|
end
|
10
20
|
|
11
|
-
|
21
|
+
def self.valid?(ssh_key)
|
22
|
+
ssh_type, encoded_key = ssh_key.split(" ")
|
23
|
+
type = SSH_TYPES.invert[ssh_type]
|
24
|
+
prefix = [0,0,0,7].pack("C*")
|
25
|
+
decoded = Base64.decode64(encoded_key)
|
26
|
+
|
27
|
+
# Base64 decoding is too permissive, so we should validate if encoding is correct
|
28
|
+
return false unless Base64.encode64(decoded).gsub("\n", "") == encoded_key
|
29
|
+
return false unless decoded.sub!(/^#{prefix}#{ssh_type}/, "")
|
30
|
+
|
31
|
+
unpacked = decoded.unpack("C*")
|
32
|
+
data = []
|
33
|
+
index = 0
|
34
|
+
until unpacked[index].nil?
|
35
|
+
datum_size = from_byte_array unpacked[index..index+4-1], 4
|
36
|
+
index = index + 4
|
37
|
+
datum = from_byte_array unpacked[index..index+datum_size-1], datum_size
|
38
|
+
data << datum
|
39
|
+
index = index + datum_size
|
40
|
+
end
|
41
|
+
|
42
|
+
SSH_CONVERSION[type].size == data.size
|
43
|
+
rescue
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.from_byte_array(byte_array, expected_size = nil)
|
48
|
+
num = 0
|
49
|
+
raise "Byte array too short" if !expected_size.nil? && expected_size != byte_array.size
|
50
|
+
byte_array.reverse.each_with_index do |item, index|
|
51
|
+
num += item * 256**(index)
|
52
|
+
end
|
53
|
+
num
|
54
|
+
end
|
12
55
|
|
13
56
|
def initialize(private_key, options = {})
|
14
|
-
|
15
|
-
|
57
|
+
begin
|
58
|
+
@key_object = OpenSSL::PKey::RSA.new(private_key)
|
59
|
+
@type = "rsa"
|
60
|
+
rescue
|
61
|
+
@key_object = OpenSSL::PKey::DSA.new(private_key)
|
62
|
+
@type = "dsa"
|
63
|
+
end
|
64
|
+
|
65
|
+
@comment = options[:comment] || ""
|
16
66
|
end
|
17
67
|
|
18
|
-
def
|
68
|
+
def private_key
|
19
69
|
key_object.to_pem
|
20
70
|
end
|
21
71
|
|
22
|
-
def
|
72
|
+
def public_key
|
23
73
|
key_object.public_key.to_pem
|
24
74
|
end
|
25
75
|
|
76
|
+
########################
|
77
|
+
# Backward compatibility
|
78
|
+
def rsa_private_key
|
79
|
+
private_key if type == "rsa"
|
80
|
+
end
|
81
|
+
|
82
|
+
def rsa_public_key
|
83
|
+
public_key if type == "rsa"
|
84
|
+
end
|
85
|
+
|
86
|
+
def dsa_private_key
|
87
|
+
private_key if type == "dsa"
|
88
|
+
end
|
89
|
+
|
90
|
+
def dsa_public_key
|
91
|
+
public_key if type == "dsa"
|
92
|
+
end
|
93
|
+
########################
|
94
|
+
|
26
95
|
def ssh_public_key
|
27
|
-
[
|
96
|
+
[SSH_TYPES[type], Base64.encode64(ssh_public_key_conversion).gsub("\n", ""), comment].join(" ").strip
|
28
97
|
end
|
29
98
|
|
30
99
|
def fingerprint
|
@@ -41,15 +110,14 @@ class SSHKey
|
|
41
110
|
# For instance, the "ssh-rsa" string is encoded as the following byte array
|
42
111
|
# [0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a']
|
43
112
|
def ssh_public_key_conversion
|
44
|
-
|
45
|
-
|
113
|
+
out = [0,0,0,7].pack("C*")
|
114
|
+
out += SSH_TYPES[type]
|
46
115
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
out += to_byte_array(n).pack("c*")
|
116
|
+
SSH_CONVERSION[type].each do |method|
|
117
|
+
byte_array = to_byte_array(key_object.public_key.send(method).to_i)
|
118
|
+
out += encode_unsigned_int_32(byte_array.length).pack("c*")
|
119
|
+
out += byte_array.pack("C*")
|
120
|
+
end
|
53
121
|
|
54
122
|
return out
|
55
123
|
end
|
@@ -71,4 +139,5 @@ class SSHKey
|
|
71
139
|
end until (num == 0 || num == -1) && (result.last[7] == num[7])
|
72
140
|
result.reverse
|
73
141
|
end
|
142
|
+
|
74
143
|
end
|
data/lib/sshkey/version.rb
CHANGED
data/test/sshkey_test.rb
CHANGED
@@ -59,28 +59,52 @@ NOAVAoGACIdfR5oZ4tvNIeqjtLF83HmUJARv86eMmjqgiQTFcZS3A8vk5y05STxX
|
|
59
59
|
HU3kTCfT6sypRi9zDQafIIyqYFgaOezr2eRRFRojQZqzHjtuFUeKLrKf7R9bzwwx
|
60
60
|
DPlNgYq8p4FOY5ZOL/ZOxUHW4vKRewURJttnxzw+LEy0T1FyAE0=
|
61
61
|
-----END RSA PRIVATE KEY-----
|
62
|
+
EOF
|
63
|
+
SSH_PRIVATE_KEY3 = <<-EOF
|
64
|
+
-----BEGIN DSA PRIVATE KEY-----
|
65
|
+
MIIBvAIBAAKBgQC8lcuXcFcIC9wsV87L6PAwYefKgK0CwTSD1v3/aabZsu4w+UF8
|
66
|
+
zsPtdsNP8+JWfOp3KFbrUTH+ODgAXF/aL4UZfpbsQe446ZFV8v6dmWqj23sk0FLX
|
67
|
+
U5l2tsuJ9OdyXetVXjBvoiz+/r4k/iG/esvWlVGEHwq5eYXgQ1GfXABY3QIVAMVe
|
68
|
+
c7skmkUrCR6iivgZYYe3PQPZAoGBAKnpdEVATtDGOW9w2evSf5kc1InzdTurcJOH
|
69
|
+
q9qYdCaa8rlMGaIS6XFWcKqBlpj0Mv2R5ldW90bU/RllGvh1KinTIRVTsf4qtZIV
|
70
|
+
Xy4vN8IYzDL1493nKndMsxsRh50rI1Snn2tssAix64eJ5VFSGlyOYEKYDMlWzHK6
|
71
|
+
Jg3tVmc6AoGBAIwTRPAEcroqOzaebiVspFcmsXxDQ4wXQZQdho1ExW6FKS8s7/6p
|
72
|
+
ItmZYXTvJDwLXgq2/iK1fRRcKk2PJEaSuJR7WeNGsJKfWmQ2UbOhqA3wWLDazIZt
|
73
|
+
cMKjFzD0hM4E8qgjHjMvKDE6WgT6SFP+tqx3nnh7pJWwsbGjSMQexpyRAhQLhz0l
|
74
|
+
GzM8qwTcXd06uIZAJdTHIQ==
|
75
|
+
-----END DSA PRIVATE KEY-----
|
62
76
|
EOF
|
63
77
|
|
64
78
|
SSH_PUBLIC_KEY1 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEArfTA/lKVR84IMc9ZzXOCHr8DVtR8hzWuEVHF6KElavRHlk14g0SZu3m908Ejm/XF3EfNHjX9wN+62IMA0QBxkBMFCuLF+U/oeUs0NoDdAEKxjj4n6lq6Ss8aLct+anMy7D1jwvOLbcwV54w1d5JDdlZVdZ6AvHm9otwJq6rNpDgdmXY4HgC2nM9csFpuy0cDpL6fdJx9lcNL2RnkRC4+RMsIB+PxDw0j3vDi04dYLBXMGYjyeGH+mIFpL3PTPXGXwL2XDYXZ2H4SQX6bOoKmazTXq6QXuEB665njh1GxXldoIMcSshoJL0hrk3WrTOG22N2CQA+IfHgrXJ+A+QUzKQ=='
|
65
79
|
SSH_PUBLIC_KEY2 = 'AAAAB3NzaC1yc2EAAAABIwAAAQEAxl6TpN7uFiY/JZ8qDnD7UrxDP+ABeh2PVg8Du1LEgXNk0+YWCeP5S6oHklqaWeDlbmAs1oHsBwCMAVpMa5tgONOLvz4JgwgkiqQEbKR8ofWJ+LADUElvqRVGmGiNEMLI6GJWeneL4sjmbb8d6U+M53c6iWG0si9XE5m7teBQSsCl0Tk3qMIkQGw5zpJeCXjZ8KpJhIJRYgexFkGgPlYRV+UYIhxpUW90t0Ra5i6JOFYwq98k5S/6SJIZQ/A9F4JNzwLw3eVxZj0yVHWxkGz1+TyELNY1kOyMxnZaqSfGzSQJTrnIXpdweVHuYh1LtOgedRQhCyiELeSMGwio1vRPKw=='
|
80
|
+
SSH_PUBLIC_KEY3 = 'AAAAB3NzaC1kc3MAAACBALyVy5dwVwgL3CxXzsvo8DBh58qArQLBNIPW/f9pptmy7jD5QXzOw+12w0/z4lZ86ncoVutRMf44OABcX9ovhRl+luxB7jjpkVXy/p2ZaqPbeyTQUtdTmXa2y4n053Jd61VeMG+iLP7+viT+Ib96y9aVUYQfCrl5heBDUZ9cAFjdAAAAFQDFXnO7JJpFKwkeoor4GWGHtz0D2QAAAIEAqel0RUBO0MY5b3DZ69J/mRzUifN1O6twk4er2ph0JpryuUwZohLpcVZwqoGWmPQy/ZHmV1b3RtT9GWUa+HUqKdMhFVOx/iq1khVfLi83whjMMvXj3ecqd0yzGxGHnSsjVKefa2ywCLHrh4nlUVIaXI5gQpgMyVbMcromDe1WZzoAAACBAIwTRPAEcroqOzaebiVspFcmsXxDQ4wXQZQdho1ExW6FKS8s7/6pItmZYXTvJDwLXgq2/iK1fRRcKk2PJEaSuJR7WeNGsJKfWmQ2UbOhqA3wWLDazIZtcMKjFzD0hM4E8qgjHjMvKDE6WgT6SFP+tqx3nnh7pJWwsbGjSMQexpyR'
|
66
81
|
|
67
82
|
KEY1_FINGERPRINT = "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
68
83
|
KEY2_FINGERPRINT = "3c:af:74:87:cc:cc:a1:12:05:1a:09:b7:7b:ce:ed:ce"
|
84
|
+
KEY3_FINGERPRINT = "14:f6:6a:12:96:be:44:32:e6:3c:77:43:94:52:f5:7a"
|
69
85
|
|
70
86
|
def setup
|
71
87
|
@key1 = SSHKey.new(SSH_PRIVATE_KEY1, :comment => "me@example.com")
|
72
88
|
@key2 = SSHKey.new(SSH_PRIVATE_KEY2, :comment => "me@example.com")
|
89
|
+
@key3 = SSHKey.new(SSH_PRIVATE_KEY3, :comment => "me@example.com")
|
73
90
|
@key_without_comment = SSHKey.new(SSH_PRIVATE_KEY1)
|
74
91
|
end
|
75
92
|
|
76
93
|
def test_private_key1
|
94
|
+
assert_equal SSH_PRIVATE_KEY1, @key1.private_key
|
77
95
|
assert_equal SSH_PRIVATE_KEY1, @key1.rsa_private_key
|
78
96
|
end
|
79
97
|
|
80
98
|
def test_private_key2
|
99
|
+
assert_equal SSH_PRIVATE_KEY2, @key2.private_key
|
81
100
|
assert_equal SSH_PRIVATE_KEY2, @key2.rsa_private_key
|
82
101
|
end
|
83
102
|
|
103
|
+
def test_private_key3
|
104
|
+
assert_equal SSH_PRIVATE_KEY3, @key3.private_key
|
105
|
+
assert_equal SSH_PRIVATE_KEY3, @key3.dsa_private_key
|
106
|
+
end
|
107
|
+
|
84
108
|
def test_ssh_public_key_decoded1
|
85
109
|
assert_equal Base64.decode64(SSH_PUBLIC_KEY1), @key1.send(:ssh_public_key_conversion)
|
86
110
|
end
|
@@ -89,6 +113,10 @@ EOF
|
|
89
113
|
assert_equal Base64.decode64(SSH_PUBLIC_KEY2), @key2.send(:ssh_public_key_conversion)
|
90
114
|
end
|
91
115
|
|
116
|
+
def test_ssh_public_key_decoded3
|
117
|
+
assert_equal Base64.decode64(SSH_PUBLIC_KEY3), @key3.send(:ssh_public_key_conversion)
|
118
|
+
end
|
119
|
+
|
92
120
|
def test_ssh_public_key_encoded1
|
93
121
|
assert_equal SSH_PUBLIC_KEY1, Base64.encode64(@key1.send(:ssh_public_key_conversion)).gsub("\n", "")
|
94
122
|
end
|
@@ -97,13 +125,42 @@ EOF
|
|
97
125
|
assert_equal SSH_PUBLIC_KEY2, Base64.encode64(@key2.send(:ssh_public_key_conversion)).gsub("\n", "")
|
98
126
|
end
|
99
127
|
|
128
|
+
def test_ssh_public_key_encoded3
|
129
|
+
assert_equal SSH_PUBLIC_KEY3, Base64.encode64(@key3.send(:ssh_public_key_conversion)).gsub("\n", "")
|
130
|
+
end
|
131
|
+
|
100
132
|
def test_ssh_public_key_output
|
101
133
|
expected1 = "ssh-rsa #{SSH_PUBLIC_KEY1} me@example.com"
|
102
134
|
expected2 = "ssh-rsa #{SSH_PUBLIC_KEY2} me@example.com"
|
103
|
-
expected3 = "ssh-
|
135
|
+
expected3 = "ssh-dss #{SSH_PUBLIC_KEY3} me@example.com"
|
136
|
+
expected4 = "ssh-rsa #{SSH_PUBLIC_KEY1}"
|
104
137
|
assert_equal expected1, @key1.ssh_public_key
|
105
138
|
assert_equal expected2, @key2.ssh_public_key
|
106
|
-
assert_equal expected3, @
|
139
|
+
assert_equal expected3, @key3.ssh_public_key
|
140
|
+
assert_equal expected4, @key_without_comment.ssh_public_key
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_ssh_public_key_validation
|
144
|
+
expected1 = "ssh-rsa #{SSH_PUBLIC_KEY1} me@example.com"
|
145
|
+
expected2 = "ssh-rsa #{SSH_PUBLIC_KEY2} me@example.com"
|
146
|
+
expected3 = "ssh-dss #{SSH_PUBLIC_KEY3} me@example.com"
|
147
|
+
expected4 = "ssh-rsa #{SSH_PUBLIC_KEY1}"
|
148
|
+
invalid1 = "ssh-rsa #{SSH_PUBLIC_KEY1}= me@example.com"
|
149
|
+
invalid2 = "ssh-rsa #{SSH_PUBLIC_KEY2}= me@example.com"
|
150
|
+
invalid3 = "ssh-dss #{SSH_PUBLIC_KEY3}= me@example.com"
|
151
|
+
invalid4 = "ssh-rsa A#{SSH_PUBLIC_KEY1}"
|
152
|
+
invalid5 = "ssh-rsa #{SSH_PUBLIC_KEY3} me@example.com"
|
153
|
+
|
154
|
+
assert SSHKey.valid?(expected1)
|
155
|
+
assert SSHKey.valid?(expected2)
|
156
|
+
assert SSHKey.valid?(expected3)
|
157
|
+
assert SSHKey.valid?(expected4)
|
158
|
+
|
159
|
+
assert !SSHKey.valid?(invalid1)
|
160
|
+
assert !SSHKey.valid?(invalid2)
|
161
|
+
assert !SSHKey.valid?(invalid3)
|
162
|
+
assert !SSHKey.valid?(invalid4)
|
163
|
+
assert !SSHKey.valid?(invalid5)
|
107
164
|
end
|
108
165
|
|
109
166
|
def test_exponent
|
@@ -119,6 +176,7 @@ EOF
|
|
119
176
|
def test_fingerprint
|
120
177
|
assert_equal KEY1_FINGERPRINT, @key1.fingerprint
|
121
178
|
assert_equal KEY2_FINGERPRINT, @key2.fingerprint
|
179
|
+
assert_equal KEY3_FINGERPRINT, @key3.fingerprint
|
122
180
|
end
|
123
181
|
|
124
182
|
def test_to_byte_array
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: sshkey
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 1.
|
5
|
+
version: 1.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- James Miller
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-02 00:00:00 -07:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -27,7 +27,7 @@ files:
|
|
27
27
|
- .gitignore
|
28
28
|
- Gemfile
|
29
29
|
- LICENSE
|
30
|
-
- README.
|
30
|
+
- README.md
|
31
31
|
- Rakefile
|
32
32
|
- lib/sshkey.rb
|
33
33
|
- lib/sshkey/version.rb
|
data/README.rdoc
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
= sshkey
|
2
|
-
|
3
|
-
Generate private/public SSH keys using Ruby without the `ssh-keygen` system command.
|
4
|
-
|
5
|
-
gem install sshkey
|
6
|
-
|
7
|
-
Tested on Ruby 1.8.7 and 1.9.2 (MRI). Ruby must be compiled with OpenSSL support.
|
8
|
-
|
9
|
-
== Usage
|
10
|
-
|
11
|
-
Generate an SSH Keypair with foo@bar.com as the comment - providing a comment is optional
|
12
|
-
|
13
|
-
k = SSHKey.generate(:comment => "foo@bar.com")
|
14
|
-
|
15
|
-
Return an SSHKey object from an existing RSA Private Key (provided as a string)
|
16
|
-
|
17
|
-
k = SSHKey.new(File.read("~/.ssh/id_rsa"), :comment => "foo@bar.com")
|
18
|
-
|
19
|
-
Both of these will return an SSHKey object with the following methods:
|
20
|
-
|
21
|
-
# Returns an OpenSSL::PKey::RSA key object
|
22
|
-
# See http://www.ruby-doc.org/stdlib/libdoc/openssl/rdoc/classes/OpenSSL/PKey/RSA.html
|
23
|
-
k.key_object
|
24
|
-
# => -----BEGIN RSA PRIVATE KEY-----\nMIIEowI...
|
25
|
-
|
26
|
-
# Returns the RSA Private Key as a string
|
27
|
-
k.rsa_private_key
|
28
|
-
# => "-----BEGIN RSA PRIVATE KEY-----\nMIIEowI..."
|
29
|
-
|
30
|
-
# Returns the RSA Public Key as a string
|
31
|
-
k.rsa_public_key
|
32
|
-
# => "-----BEGIN RSA PUBLIC KEY-----\nMIIBCg..."
|
33
|
-
|
34
|
-
# Returns the SSH Public Key as a string
|
35
|
-
k.ssh_public_key
|
36
|
-
# => "ssh-rsa AAAAB3NzaC1yc2EA...."
|
37
|
-
|
38
|
-
# Returns the comment as a string
|
39
|
-
k.comment
|
40
|
-
# => "foo@bar.com"
|
41
|
-
|
42
|
-
# Returns the fingerprint as a string
|
43
|
-
k.fingerprint
|
44
|
-
# => "2a:89:84:c9:29:05:d1:f8:49:79:1c:ba:73:99:eb:af"
|
45
|
-
|
46
|
-
== Copyright
|
47
|
-
|
48
|
-
Copyright (c) 2011 James Miller
|