Issue
I have been designing a blockchain based cryptocurrency and some of the blocks on the blockchain can have their data updated by the owner of the block. I tried implementing an ssh style of public key authentication: client generates a key pair and sends the public key over to the block where it allows the public keys listed under "admins" to change meta data of the block. The problem with this is that someone can send random known public keys to see if they are allowed to edit meta data, how does ssh prevent people from just sending some sort of string with a known public key to access the contents of the ssh? (I ask this because I want to implement something similar to my context)
Solution
Not sure if this is really a programming question, but:
SSH uses publickey keys to authenticate 'hosts' (servers) always and 'users' (clients) optionally (but often). The commonly used and de-facto standard implementation OpenSSH, for the latter case, uses a file for each user on the server, normally located under the user's home directory as $HOME/.ssh/authorized_keys
, which lists the publickeys valid for that user. If the client process specifies a username and a publickey listed in that user's authorized_keys file, and uses the privatekey to sign certain data including a connection secret and nonces, that is considered to prove the identity of the user. (See RFC 4252 for details, but start with 4253 for context.) Other implementations need to have equivalent data, although not necessarily that exact file. The host/server usually allows the user/client to make several attempts, in case it has multiple keys and/or other methods to try, but this is configurable.
SSH by itself mostly doesn't control access; it just establishes the user/client's identity as a username configured on the 'host'. Using that identity to control access -- what security people call authorization as opposed to identification and authentication -- depends on the host. Many SSH hosts are Unix, and for Unix the same rules apply to accessing Unix over SSH as apply to other kinds of connection: this starts with the classic 'chmod bits' on each file allowing read,write,execute to user,group,other, and can include other things like ACLs, SELinux attributes, sudo rules, group match for signalling processes, special configuration of some things like NFS, and so on and so on. If the SSH host/server is NOT Unix, what security rules or policies it applies once you have connected and authenticated it are up to it and may be quite different.
OpenSSH (on a Unix host) also implements a few options in the authorized_keys
file that impose additional restrictions on what the client can do (over that connection); see man sshd on your system or here under AUTHORIZED_KEYS FILE FORMAT. In addition, as noted there, OpenSSH supports a level of indirection: instead of directly listing every key in each applicable user's authorized_keys file you can use a (designated) 'CA' key to sign other keys, and then configure authorized_keys to accept any key signed by a listed CA key. These certificates can themselves include some restrictions; see man ssh-keygen under CERTIFICATES. This can be more convenient in a large environment with many users, hosts, or both.
Answered By - dave_thompson_085