Return a public key fingerprint based on its base64-encoded representation

    The fingerprint string is formatted according to RFC 4716 (ch.4), that is,
    in the form "xx:xx:...:xx"

    If the key is invalid (incorrect base64 string), return None

    public_key
        The public key to return the fingerprint for

    fingerprint_hash_type
        The public key fingerprint hash type that the public key fingerprint
        was originally hashed with. This defaults to ``sha256`` if not specified.

        .. versionadded:: 2016.11.4
        .. versionchanged:: 2017.7.0: default changed from ``md5`` to ``sha256``

def _fingerprint(public_key, fingerprint_hash_type):
    '''
    Return a public key fingerprint based on its base64-encoded representation

    The fingerprint string is formatted according to RFC 4716 (ch.4), that is,
    in the form "xx:xx:...:xx"

    If the key is invalid (incorrect base64 string), return None

    public_key
        The public key to return the fingerprint for

    fingerprint_hash_type
        The public key fingerprint hash type that the public key fingerprint
        was originally hashed with. This defaults to ``sha256`` if not specified.

        .. versionadded:: 2016.11.4
        .. versionchanged:: 2017.7.0: default changed from ``md5`` to ``sha256``

    '''
    if fingerprint_hash_type:
        hash_type = fingerprint_hash_type.lower()
    else:
        hash_type = 'sha256'

    try:
        hash_func = getattr(hashlib, hash_type)
    except AttributeError:
        raise CommandExecutionError(
            'The fingerprint_hash_type {0} is not supported.'.format(
                hash_type
            )
        )

    try:
        if six.PY2:
            raw_key = public_key.decode('base64')
        else:
            raw_key = base64.b64decode(public_key, validate=True)  # pylint: disable=E1123
    except binascii.Error:
        return None

    ret = hash_func(raw_key).hexdigest()

    chunks = [ret[i:i + 2] for i in range(0, len(ret), 2)]
    return ':'.join(chunks)