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.4.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.4-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: sshkeyring-0.0.4.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.4.tar.gz
Algorithm Hash digest
SHA256 5d027c21b5e6242b59c4f14900e0aec2e3f4e5c2dea87fbd1a412968aa7e05d8
MD5 5cdafe630c423bad178cef297b2940e9
BLAKE2b-256 3cb61c31d3acb59b37d85f52600385b05ecad01481295fce30d07bcedd92a8f0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: sshkeyring-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 25.5 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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 56174f02923773137f23d77650c9c9f923a5f83d21afcb0d0e474655e4ab6bc2
MD5 b0acdd70001f80e93635a3c6dbc30914
BLAKE2b-256 35255a07c9a0c27b7d648d8f967f07baaed83dad29962d7589938092ff39e706

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