Skip to main content

Utilities to manage SSH key in key files and ssh-agent

Project description

Utilities to manage SSH key in key files and ssh-agent.

It can be used the query ssh key infomation from the local directory and/or ssh-agent, and the sign the data by selected ssh-key, and etc.

Requirement

  • cryptography

  • paramiko

  • PyNaCl

  • setuptools

  • pkgstruct : for the example script

Usage

  • class SSHKeyInfo : Structure to store the key information

  • class SSHKeyUtil : Utilities functions to manage SSH keys with file I/O and/or ssh-agent

  • class SSHKeyRing (inherited from SSHKeyUtil) : Utility for storing the information of the avaiable SSH Keys

Functionalities

  • sshkeyring.paramiko_supplement: Add member functions to class paramiko.agent.AgentKey and class paramiko.agent.Agent.

    • paramiko.agent.AgentKey.get_openssh_pubkey(verbose=False) : Return the public key (string) with openssh compatible format

    • paramiko.agent.AgentKey.dump(show_publickey=False, stream=sys.stdout) : Output (fingerprint) of the public key (string) with compatible format by ssh-add -l/-L

    • paramiko.agent.AgentKey.get_type() : Return the key type(dsa, ecdsa, ed25519, rsa)

    • paramiko.agent.Agent.ssh_add_key(key : paramiko.pkey.PKey, key_comment: str="") : Register the private key to ssh-agent

    • paramiko.agent.Agent.fetch_agent_keylist(verbose=False) : Fetch the list of the registered keys from ssh-agent

  • sshkeyring.sshkeyutil: class SSHKeyInfo

    • Key information properties

      - `key_id` : `str` : The name of the key
      - `key_type` : `str` :  Key type strings (`dsa`, `ecdsa`, `ed25519`, `rsa`)
      - `agent_client` : `paramiko.agent.Agent` object that connects to ssh-agent contains this key.
      - `agent_key` : `paramiko.agent.AgentKey` object that contains ssh-agent key information.
      - `agent_sock` : `str` : path of the socket file for the connection w/ ssh-agent.
      - `local_key` : `paramiko.pkey.PKey` : object that is constructed with local private key file
      - `public_blob` : `paramiko.pkey.PublicBlob` : public key contents constructed with local public key file
      - `path_private_key` : `str` : the path of the private key file.
      - `path_public_key` : `str` : the path of the public key file.
      - `private_key` : one of `cryptography.hazmat.primitives.asymmetric.types.PrivateKeyTypes` : private key object
      - `public_key` : one of `cryptography.hazmat.primitives.asymmetric.types.PublicKeyTypes`:  public key object
      - `private_key_data` : `str` : private key strings read from key file
      - `public_key_data` : `str` : public key strings read from key file
      - `passphrase` : `str` : buffer to store the pashphrase for the  encryption of the privete key file

Install

% pip install sshkeyring

Examples

– see example/sshkeyscan.py

# ....

import pkgstruct
import sshkeyring
# ....

def main():

    pkg_info=pkgstruct.PkgStruct(script_path=sys.argv[0])
    pkg_keydir_prefix=pkg_info.concat_path('pkg_statedatadir', 'pki')


    ......
    # Key is identified with the tuple '(key_id(i.e. key_name), key_type('rsa', ...) )'


    argpsr = argparse.ArgumentParser(description='SSH key utilities')
    ......
    argpsr.add_argument('-t', '--key-type', choices=sshkeyring.SSHKeyUtil.KEY_TYPES, default=None, help='Specify Key Type')
    argpsr.add_argument('-i', '--key-id',   default=None,
                        help=('Specify key id: Default is %s' % ( sshkeyring.SSHKeyUtil.Default_Key_Id(),) ))
    argpsr.add_argument('-U', '--use-openssh-keys', default=None, action='store_true',
                        help=( 'Use openssh keys (in %s)' % (sshkeyring.SSHKeyUtil.SEEK_OPENSSH_KEYDIR_DEFAULT,)))
    argpsr.add_argument('-p', '--passphrase', type=str, default=None, help='SSH key passphrase (common)')
    ......
    argpsr.add_argument('data', nargs='*', type=str, default=None,  help='Date to sign')
    opts = argpsr.parse_args()


    # Determine (key_id, key_type): CLI options or default name and type
    use_key_id   = opts.key_id   if isinstance(opts.key_id,   str) and opts.key_id   else sshkeyring.SSHKeyRing.Default_Key_Id()
    use_key_type = opts.key_type if isinstance(opts.key_type, str) and opts.key_type else sshkeyring.SSHKeyUtil.KEY_TYPE_DEFAULT

    # Initialize the SSHKeyring object
    skyrng = sshkeyring.SSHKeyRing(keyfile_basename_default = opts.keyfile_basename,
                                   seek_openssh_keydir_default = opts.use_openssh_keys,
                                   passphrase = opts.passphrase)

    # Scan ssh-keys in the ssh-agent and the local directories
    skyrng.refresh_keyinfo(use_local_key=True, # Scan local ssh-key files
                           seek_openssh_dir=opts.use_openssh_keys,
                           decode_private_key=False,
                           passphrase=opts.passphrase,
                           invoke_agent=True, # if no ssh-agent is running, new ssh-agent process is invoked.
                           )

    # Show the list of ssh-keys
    skyrng.dump()
    # Shoe the list of ssh-keys like `ssh-add -l/-L`
    skyrng.dump_agent_keys(key_name=opts.key_id, show_publickey=False)
    skyrng.dump_agent_keys(key_name=opts.key_id, show_publickey=True)

    # Pickup the SSHKeyInfo object to use from the stored list
    # if the specified key is not in the stored list, None is returned.
    picked_keyinfo = skyrng.pickup_keyinfo(key_id=opts.key_id, key_type=opts.key_type)

    if picked_keyinfo is None and opts.create_keys:
        # New key will be generated and registered to ssh-agent.
        new_keyinfo, ssh_add_status = skyrng.setup_new_sshkey(key_id=opts.key_id,
                                                                  key_type=opts.key_type,
                                                                  key_bits=opts.key_bits,
                                                                  passphrase=opts.passphrase,
                                                                  register_agent=(not opts.disuse_ssh_agent),
                                                                  keydir_prefix=None,
                                                                  privatekey_dir=None,
                                                                  publickey_dir=None,
                                                                  keyfile_basename=opts.keyfile_basename,
                                                                  privatekey_ext=None,
                                                                  publickey_ext=None,
                                                                  force_overwrite=opts.allow_keyfile_overwrite,
                                                                  ecdsa_ec_type="secp256r1",
                                                                  rsa_public_exponent=65537,
                                                                  min_passphrase_length=opts.passphrase_length_min,
                                                                  verbose=opts.verbose)
         # Pickup the new SSHKeyInfo object from the stored list
         picked_keyinfo = skyrng.pickup_keyinfo(key_id=opts.key_id, key_type=opts.key_type)


     # Register private key to ssh-agent when it is not regeiterd yet
     if not opts.disuse_ssh_agent:
        if picked_keyinfo.agent_key is None:
            # Decode from the encrypted private key
            picked_keyinfo.set_passphrase(passphrase=opts.passphrase, overwrite=False, min_passphrase_length=8, verbose=opts.verbose)
            picked_keyinfo.load_local_key(passphrase=opts.passphrase, verbose=opts.verbose)
            # register to ssh-agent
            skyrng.ssh_add_keyinfo(picked_keyinfo, verbose=opts.verbose)

     #
     # sample for ssh-key use
     #
     for data_idx, raw_data in enumerate(opts.data):
        # decode from the encrypted private key if necessary
        if opts.disuse_ssh_agent or opts.verify_sign:
            picked_keyinfo.load_local_key(passphrase=opts.passphrase, verbose=opts.verbose)

        # Sign the data bu using the selected SSH private key
        bytes_signed = picked_keyinfo.sign_ssh_data(data=raw_data, algorithm=opts.sign_algorithm,
                                                    use_local_key=opts.disuse_ssh_agent, verbose=opts.verbose)
        # Base-64 encoded signature
        b64data_signed = base64.b64encode(bytes_signed).decode('utf-8')


        # Verify the signature and data by using public key.
        if opts.verify_sign:
            flg_verified = picked_keyinfo.verify_ssh_sig_by_keyfile(data=raw_data, sig=bytes_signed, verbose=opts.verbose)
            verified_status_txt = "Verified" if flg_verified else "Invalid"
        else:
            flg_verified = None
            verified_status_txt = "Unverified"

        if data_idx==0:
            print("--------------------------------------------------")
        print("Raw Data  : %s" % (raw_data, ))
        print("Signature : %s" % (b64data_signed,))
        print("Status    : %s" % (verified_status_txt,))
        print("--------------------------------------------------")

Author

Nanigashi Uji (53845049+nanigashi-uji@users.noreply.github.com)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sshkeyring-0.0.5.tar.gz (30.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sshkeyring-0.0.5-py3-none-any.whl (25.4 kB view details)

Uploaded Python 3

File details

Details for the file sshkeyring-0.0.5.tar.gz.

File metadata

  • Download URL: sshkeyring-0.0.5.tar.gz
  • Upload date:
  • Size: 30.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for sshkeyring-0.0.5.tar.gz
Algorithm Hash digest
SHA256 142d58efefcaa5352f1d53c0a187534eb2e78f716e4928f817aee0e1c3ff5d5f
MD5 46da0248510d757bf30a3778cb33c073
BLAKE2b-256 3fa014817afcad9e0516a746485eabf3e8a604819626adf9001a08340748675b

See more details on using hashes here.

File details

Details for the file sshkeyring-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: sshkeyring-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 25.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.2

File hashes

Hashes for sshkeyring-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 82c2ff00e842adee8ce69fd4c0ea4bf7fc8dca399a040dc14eba5b188c2d0235
MD5 56bb0480eb47fd71b43eb527adf2ac97
BLAKE2b-256 7b0686b79f81ab0307bde6a20d0ef6e6aa699a8a4274d504ac137721ed242d57

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page