bensie / sshkey Goto Github PK
View Code? Open in Web Editor NEWSSH private and public key generator in pure Ruby (RSA & DSA)
License: MIT License
SSH private and public key generator in pure Ruby (RSA & DSA)
License: MIT License
Looks like there may be better choice code.
k = SSHKey.new( File.read( 'spec/keys/ed25519' ) )
OpenSSL::PKey::DSAError: Neither PUB key nor PRIV key
from .bundle-gems/ruby/2.7.0/gems/sshkey-2.0.0/lib/sshkey.rb:250:in `initialize'
Caused by OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key: nested asn1 error
from .bundle-gems/ruby/2.7.0/gems/sshkey-2.0.0/lib/sshkey.rb:247:in `initialize'
I saw that it's not feasible at the moment to implement generating ECDSA keys based on this closed issue: #15
What about adding support to #valid_ssh_public_key?
to be able to validate ECDSA keys?
Would be nice to have method to have private key generated also for PuTTY https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
Is it valid to add multiline comments at the end?
> require 'sshkey'
> s = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAs8S3Nj3JhcKd6XxNyN99e+TJdA2S1BM8++pKYeTQZzH62ij8jAvClHMJB13Lt7XcLqmO3MoSSJ+cXotSmurT70xaKp5ScGL0cY/4oIswdjIxqttoIBQ1CgfBM2JvHvRA9WstnlOmVd3VOSGknHt4NqPou8e0nuJF++08EthzPF1k+Is4TP7ySGAy5XLUfpvzxEhqXqkKDPADCoLW/N09GjASlft8AyliatpAuoHgM0Hul+808uIDPHkwPT4Dp6Fwnk1oNY2iT2vk5wtJ+SoXcPHXMJH8NqNxMG4CA5cew9NZGlKOEwxhnu2V3iOWCjL+sOylWMatbfAuLSex0Ra7aw=="
> SSHKey.valid_ssh_public_key? s
=> true
> s << "\n some invalid text"
> SSHKey.valid_ssh_public_key? s
=> true
I wanted to use this gem to verify if the public keys that we retrieve from Github are valid before overwriting authorized_keys
on servers using Capistrano. For instance, 404 or 500 may return html tags rather than keys.
task :ssh do
require 'open-uri'
require 'sshkey'
keys = ['foo', 'bar', 'baz'].map do |name|
open("https://github.com/#{name}.keys").read
end.join("\n") << "\n"
abort "Invalid keys:\n#{keys}" unless SSHKey.valid_ssh_public_key?(keys)
put keys, '/home/deploy/.ssh/authorized_keys', mode: 0600
end
Thought it would be nice if we could just do:
abort "Invalid keys:\n#{keys}" unless SSHKey.valid_ssh_public_key?(keys, multiline: true)
Rather than this:
abort "Invalid keys:\n#{keys}" unless keys.split("\n").all?{|i| SSHKey.valid_ssh_public_key(i) }
AuthorizedKeysFile containing public ssh key(s) can contain empty lines and/or lines starting with a โ#โ as comments.
Let's treat provided public key to a library in the same way.
Could you add this feature: split ssh public key to key itself and the comment, so they could be processed separately?
The problem appears to be in the validation of some properties:
https://github.com/bensie/sshkey/blob/master/lib/sshkey.rb#L62
It checks for num_bytes == 32
, but this is not true for both my key and @BluSyn key:
Problematic key:
$ python test.py b'AAAAC3NzaC1lZDI1NTE5AAAAIACf9lz1m7U/sTRyBkxhHDR0ncKIr0NIKzgfe3sQbUnN' seg b'ssh-ed25519' seg b'\x00\x9f\xf6\\\xf5\x9b\xb5?\xb14r\x06La\x1c4t\x9d\xc2\x88\xafCH+8\x1f{{\x10mI\xcd'
Other problematic key:
$ python test.py b'AAAAC3NzaC1lZDI1NTE5AAAAIADK9x9t3yQQH7h4OEJpUa7l2j7mcmKf4LAsNXHxNbSm' seg b'ssh-ed25519' seg b'\x00\xca\xf7\x1fm\xdf$\x10\x1f\xb8x8BiQ\xae\xe5\xda>\xe6rb\x9f\xe0\xb0,5q\xf15\xb4\xa6'
Random other key:
b'AAAAC3NzaC1lZDI1NTE5AAAAIAaSKub+wcrv/6ywfl2PqDVMSG56jDUOCgK0nsvXxxBc' seg b'ssh-ed25519' seg b'\x06\x92*\xe6\xfe\xc1\xca\xef\xff\xac\xb0~]\x8f\xa85LHnz\x8c5\x0e\n\x02\xb4\x9e\xcb\xd7\xc7\x10\\'
So the bignum starting with a zero somehow causes ruby's bignum num_bytes to be 31 (which kind of makes sense - it's probably the same in openssl and not a bug in that binding?).
So bug appears to be in the == 32 check. It's 31 for the other keys.
import struct import base64 # Random good key orig = b'AAAAC3NzaC1lZDI1NTE5AAAAIAaSKub+wcrv/6ywfl2PqDVMSG56jDUOCgK0nsvXxxBc' # Bad key 1 #orig = b'AAAAC3NzaC1lZDI1NTE5AAAAIACf9lz1m7U/sTRyBkxhHDR0ncKIr0NIKzgfe3sQbUnN' # Bad key 2 #orig = b'AAAAC3NzaC1lZDI1NTE5AAAAIADK9x9t3yQQH7h4OEJpUa7l2j7mcmKf4LAsNXHxNbSm' r = base64.b64decode(orig) rr = base64.b64encode(r) assert orig == rr, 'What' print(orig) while len(r): front = r[0:4] r = r[4:] size = struct.unpack('>i', front)[0] seg = r[0:size] r = r[size:] print('seg', seg)
k = SSHKey.generate
=> #<SSHKey:0x8ad5950 @type="rsa", @comment="", @Passphrase=nil, @key_object=-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA8mWCKsyGY1d/vYfYh6Cd+Y9gAIJBBA11esN1ETCnlqi3f+lh
......
k.directives = ['no-pty']
NoMethodError: undefined method directives=' for #<SSHKey:0x8adf61c> from (irb):3 from /home/x/.rvm/rubies/ruby-1.9.3-p327-falcon/bin/irb:16:in
Same results from gem install or git checkout.
OpenSSH supports ssh certificates. It would be very useful, if the lib supported evaluating those and providing useful methods like:
While playing with Mozilla's ssh_scan tool, which utilizes your library, I noticed the reported key sizes for ecdsa keys are wrong. I looked at your code and was able to reproduce this by calling the ssh_public_key_bits
function on your test keys. It seems there are no test cases for ecdsa key size calculations so this probably came unnoticed.
irb(main):013:0> SSHKey.ssh_public_key_bits "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHJFDZ5qymZfIzoJcxYeu3C9HjJ08QAbqR28C2zSMLwcb3ZzWdRApnj6wEgRvizsBmr9zyPKb2u5Rp0vjJtQcZo="
=> 520
irb(main):014:0> SSHKey.ssh_public_key_bits "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBP+GtUCOR8aW7xTtpkbJS0qqNZ98PgbUNtTFhE+Oe+khgoFMX+o0JG5bckVuvtkRl8dr+63kUK0QPTtzP9O5yixB9CYnB8CgCgYo1FCXZuJIImf12wW5nWKglrCH4kV1Qg=="
=> 776
irb(main):015:0> SSHKey.ssh_public_key_bits "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACsunidnIZ77AjCHSDp/xknLGDW3M0Ia7nxLdImmp0XGbxtbwYm2ga5XUzV9dMO9wF9ICC3OuH6g9DtGOBNPru1PwFDjaPISGgm0vniEzWazLsvjJVLThOA3VyYLxmtjm0WfS+/DfxgWVS6oeCTnDjjoVVpwU/fDbUbYPPRZI84/hOGNA=="
=> 1064
As one can see, the estimated key sizes are 520, 776 and 1064 bits respectively, while they actually are 256, 384 and 521.
Sadly I can't send in a PR to fix this since I have no experience with Ruby development.
/cc @claudijd
Hi!
Does it support ECDSA key format? At least for public key validation?
Is there a method to decrypt the private key?
There is a small mistake in the "Use your existing key" example in the README:
#!/usr/bin/env ruby
require 'sshkey'
k = SSHKey.new(File.read("~/.ssh/id_rsa"), comment: "[email protected]")
~ % ls ~/.ssh/id_rsa.pub
/home/sometimesfood/.ssh/id_rsa.pub
~ % ./pubkeytest.rb
./pubkeytest.rb:5:in `read': No such file or directory @ rb_sysopen - ~/.ssh/id_rsa.pub (Errno::ENOENT)
from ./pubkeytest.rb:5:in `<main>'
I'll submit a pull request to fix this.
Is there plan to add support for Ruby 2.4 and later? There are changes in OpenSSL that break this library in OpenSSL 2.x.x
Hi,
Is it possible to add a passphrase to the key that is created with your library?
Regards,
Carl
This can be used to convert RSA keys to SSH keys and to convert SSH to SSH2 keys. Any thoughts on adding support for converting SSH public keys to RSA public keys?
Hey,
I have the following:
key = SSHKey.generate(comment: "blah-dev-#{server.id}")
raise key.private_key.to_json
I then save that key locally, and try and and run ssh-add
on the key. It asks me for a passphrase.
Looking through the code, i cannot find where this is happening. But basically, it's always setting a passphrase by the looks of it.
Thanks
Scott
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.