sshkeyring
==========
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)
Raw data
{
"_id": null,
"home_page": "https://github.com/nanigashi-uji/sshkeyring.git",
"name": "sshkeyring",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "ssh-keyfile utility ssh-agent utility",
"author": "Nanigashi Uji",
"author_email": "53845049+nanigashi-uji@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/26/21/bc4cfa73c5ed2e668ba56361f84909f95ea4f916e6a0d79849ea81dd448d/sshkeyring-0.0.3.tar.gz",
"platform": null,
"description": "sshkeyring\n==========\n\nUtilities to manage SSH key in key files and ssh-agent.\n\nIt can be used the query ssh key infomation from the local directory\nand/or ssh-agent, and the sign the data by selected ssh-key, and etc.\n\nRequirement\n-----------\n\n- cryptography\n- paramiko\n- PyNaCl\n- setuptools\n- pkgstruct : for the example script\n\nUsage\n-----\n\n- class ``SSHKeyInfo`` : Structure to store the key information\n\n- class ``SSHKeyUtil`` : Utilities functions to manage SSH keys with\n file I/O and/or ssh-agent\n\n- class SSHKeyRing (inherited from SSHKeyUtil) : Utility for storing\n the information of the avaiable SSH Keys\n\nFunctionalities\n---------------\n\n- sshkeyring.paramiko_supplement: Add member functions to class\n ``paramiko.agent.AgentKey`` and class ``paramiko.agent.Agent``.\n\n - ``paramiko.agent.AgentKey.get_openssh_pubkey(verbose=False)`` :\n Return the public key (string) with openssh compatible format\n - ``paramiko.agent.AgentKey.dump(show_publickey=False, stream=sys.stdout)``\n : Output (fingerprint) of the public key (string) with compatible\n format by ``ssh-add -l/-L``\n - ``paramiko.agent.AgentKey.get_type()`` : Return the key\n type(``dsa``, ``ecdsa``, ``ed25519``, ``rsa``)\n - ``paramiko.agent.Agent.ssh_add_key(key : paramiko.pkey.PKey, key_comment: str=\"\")``\n : Register the private key to ssh-agent\n - ``paramiko.agent.Agent.fetch_agent_keylist(verbose=False)`` :\n Fetch the list of the registered keys from ssh-agent\n\n- sshkeyring.sshkeyutil: ``class SSHKeyInfo``\n\n - Key information properties\n\n ::\n\n - `key_id` : `str` : The name of the key\n - `key_type` : `str` : Key type strings (`dsa`, `ecdsa`, `ed25519`, `rsa`)\n - `agent_client` : `paramiko.agent.Agent` object that connects to ssh-agent contains this key.\n - `agent_key` : `paramiko.agent.AgentKey` object that contains ssh-agent key information.\n - `agent_sock` : `str` : path of the socket file for the connection w/ ssh-agent.\n - `local_key` : `paramiko.pkey.PKey` : object that is constructed with local private key file\n - `public_blob` : `paramiko.pkey.PublicBlob` : public key contents constructed with local public key file\n - `path_private_key` : `str` : the path of the private key file. \n - `path_public_key` : `str` : the path of the public key file. \n - `private_key` : one of `cryptography.hazmat.primitives.asymmetric.types.PrivateKeyTypes` : private key object\n - `public_key` : one of `cryptography.hazmat.primitives.asymmetric.types.PublicKeyTypes`: public key object\n - `private_key_data` : `str` : private key strings read from key file\n - `public_key_data` : `str` : public key strings read from key file\n - `passphrase` : `str` : buffer to store the pashphrase for the encryption of the privete key file\n\nInstall\n-------\n\n::\n\n % pip install sshkeyring\n\nExamples\n--------\n\n\u2013 see ``example/sshkeyscan.py``\n\n::\n\n # ....\n\n import pkgstruct\n import sshkeyring\n # ....\n\n def main():\n\n pkg_info=pkgstruct.PkgStruct(script_path=sys.argv[0])\n pkg_keydir_prefix=pkg_info.concat_path('pkg_statedatadir', 'pki')\n\n \n ......\n # Key is identified with the tuple '(key_id(i.e. key_name), key_type('rsa', ...) )'\n\n\n argpsr = argparse.ArgumentParser(description='SSH key utilities')\n ......\n argpsr.add_argument('-t', '--key-type', choices=sshkeyring.SSHKeyUtil.KEY_TYPES, default=None, help='Specify Key Type')\n argpsr.add_argument('-i', '--key-id', default=None,\n help=('Specify key id: Default is %s' % ( sshkeyring.SSHKeyUtil.Default_Key_Id(),) ))\n argpsr.add_argument('-U', '--use-openssh-keys', default=None, action='store_true',\n help=( 'Use openssh keys (in %s)' % (sshkeyring.SSHKeyUtil.SEEK_OPENSSH_KEYDIR_DEFAULT,)))\n argpsr.add_argument('-p', '--passphrase', type=str, default=None, help='SSH key passphrase (common)')\n ......\n argpsr.add_argument('data', nargs='*', type=str, default=None, help='Date to sign')\n opts = argpsr.parse_args()\n\n\n # Determine (key_id, key_type): CLI options or default name and type\n use_key_id = opts.key_id if isinstance(opts.key_id, str) and opts.key_id else sshkeyring.SSHKeyRing.Default_Key_Id()\n use_key_type = opts.key_type if isinstance(opts.key_type, str) and opts.key_type else sshkeyring.SSHKeyUtil.KEY_TYPE_DEFAULT\n\n # Initialize the SSHKeyring object\n skyrng = sshkeyring.SSHKeyRing(keyfile_basename_default = opts.keyfile_basename,\n seek_openssh_keydir_default = opts.use_openssh_keys,\n passphrase = opts.passphrase)\n\n # Scan ssh-keys in the ssh-agent and the local directories\n skyrng.refresh_keyinfo(use_local_key=True, # Scan local ssh-key files\n seek_openssh_dir=opts.use_openssh_keys,\n decode_private_key=False,\n passphrase=opts.passphrase,\n invoke_agent=True, # if no ssh-agent is running, new ssh-agent process is invoked.\n ) \n\n # Show the list of ssh-keys\n skyrng.dump()\n # Shoe the list of ssh-keys like `ssh-add -l/-L`\n skyrng.dump_agent_keys(key_name=opts.key_id, show_publickey=False)\n skyrng.dump_agent_keys(key_name=opts.key_id, show_publickey=True)\n\n # Pickup the SSHKeyInfo object to use from the stored list\n # if the specified key is not in the stored list, None is returned.\n picked_keyinfo = skyrng.pickup_keyinfo(key_id=opts.key_id, key_type=opts.key_type)\n\n if picked_keyinfo is None and opts.create_keys:\n # New key will be generated and registered to ssh-agent.\n new_keyinfo, ssh_add_status = skyrng.setup_new_sshkey(key_id=opts.key_id,\n key_type=opts.key_type,\n key_bits=opts.key_bits,\n passphrase=opts.passphrase,\n register_agent=(not opts.disuse_ssh_agent),\n keydir_prefix=None,\n privatekey_dir=None,\n publickey_dir=None,\n keyfile_basename=opts.keyfile_basename,\n privatekey_ext=None,\n publickey_ext=None,\n force_overwrite=opts.allow_keyfile_overwrite,\n ecdsa_ec_type=\"secp256r1\",\n rsa_public_exponent=65537,\n min_passphrase_length=opts.passphrase_length_min,\n verbose=opts.verbose)\n # Pickup the new SSHKeyInfo object from the stored list \n picked_keyinfo = skyrng.pickup_keyinfo(key_id=opts.key_id, key_type=opts.key_type)\n\n\n # Register private key to ssh-agent when it is not regeiterd yet \n if not opts.disuse_ssh_agent:\n if picked_keyinfo.agent_key is None:\n # Decode from the encrypted private key\n picked_keyinfo.set_passphrase(passphrase=opts.passphrase, overwrite=False, min_passphrase_length=8, verbose=opts.verbose)\n picked_keyinfo.load_local_key(passphrase=opts.passphrase, verbose=opts.verbose)\n # register to ssh-agent\n skyrng.ssh_add_keyinfo(picked_keyinfo, verbose=opts.verbose)\n\n #\n # sample for ssh-key use\n #\n for data_idx, raw_data in enumerate(opts.data):\n # decode from the encrypted private key if necessary\n if opts.disuse_ssh_agent or opts.verify_sign:\n picked_keyinfo.load_local_key(passphrase=opts.passphrase, verbose=opts.verbose)\n\n # Sign the data bu using the selected SSH private key \n bytes_signed = picked_keyinfo.sign_ssh_data(data=raw_data, algorithm=opts.sign_algorithm, \n use_local_key=opts.disuse_ssh_agent, verbose=opts.verbose)\n # Base-64 encoded signature \n b64data_signed = base64.b64encode(bytes_signed).decode('utf-8')\n\n \n # Verify the signature and data by using public key.\n if opts.verify_sign:\n flg_verified = picked_keyinfo.verify_ssh_sig_by_keyfile(data=raw_data, sig=bytes_signed, verbose=opts.verbose)\n verified_status_txt = \"Verified\" if flg_verified else \"Invalid\"\n else:\n flg_verified = None\n verified_status_txt = \"Unverified\"\n\n if data_idx==0:\n print(\"--------------------------------------------------\")\n print(\"Raw Data : %s\" % (raw_data, ))\n print(\"Signature : %s\" % (b64data_signed,))\n print(\"Status : %s\" % (verified_status_txt,))\n print(\"--------------------------------------------------\")\n\nAuthor\n------\n\n::\n\n Nanigashi Uji (53845049+nanigashi-uji@users.noreply.github.com)\n",
"bugtrack_url": null,
"license": "BSD-3-Clause",
"summary": "Utilities to manage SSH key in key files and ssh-agent",
"version": "0.0.3",
"project_urls": {
"Homepage": "https://github.com/nanigashi-uji/sshkeyring.git"
},
"split_keywords": [
"ssh-keyfile",
"utility",
"ssh-agent",
"utility"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "5c7faee1d761b2f033dca8df455c8064f9c28cbd5e218de0ae4523628b69fb70",
"md5": "84218823e5eeca8c9bfc10a777bbcd44",
"sha256": "ac78233d77c7da05acd649e19bc6219dbae8eeaefc20fa7b4bc1a09df291fd5f"
},
"downloads": -1,
"filename": "sshkeyring-0.0.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "84218823e5eeca8c9bfc10a777bbcd44",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 25471,
"upload_time": "2025-02-19T03:03:08",
"upload_time_iso_8601": "2025-02-19T03:03:08.962589Z",
"url": "https://files.pythonhosted.org/packages/5c/7f/aee1d761b2f033dca8df455c8064f9c28cbd5e218de0ae4523628b69fb70/sshkeyring-0.0.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "2621bc4cfa73c5ed2e668ba56361f84909f95ea4f916e6a0d79849ea81dd448d",
"md5": "ffcd1b1902044d674ac59054a75a1fae",
"sha256": "d55e119b7eaf6f3f724398668b9231154b23dfef7077f8e4b1c9ef24dc49f7c0"
},
"downloads": -1,
"filename": "sshkeyring-0.0.3.tar.gz",
"has_sig": false,
"md5_digest": "ffcd1b1902044d674ac59054a75a1fae",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 30452,
"upload_time": "2025-02-19T03:03:13",
"upload_time_iso_8601": "2025-02-19T03:03:13.181116Z",
"url": "https://files.pythonhosted.org/packages/26/21/bc4cfa73c5ed2e668ba56361f84909f95ea4f916e6a0d79849ea81dd448d/sshkeyring-0.0.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-19 03:03:13",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "nanigashi-uji",
"github_project": "sshkeyring",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "cryptography",
"specs": []
},
{
"name": "paramiko",
"specs": []
},
{
"name": "pkgstruct",
"specs": []
},
{
"name": "PyNaCl",
"specs": []
}
],
"lcname": "sshkeyring"
}