or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

encryption-decryption.mdgpg-instance.mdindex.mdkey-discovery.mdkey-management.mdkeyserver-operations.mdsigning-verification.md
tile.json

signing-verification.mddocs/

Digital Signing and Verification

Digital signature creation and verification operations for data integrity and authenticity, supporting multiple signature formats and comprehensive verification.

Capabilities

Digital Signing

Create digital signatures for data integrity and authenticity verification with support for clear-text signing, detached signatures, and binary signatures.

def sign(self, message, **kwargs):
    """
    Sign a message string.
    
    Parameters:
    - message (str): Data to sign
    - keyid (str): Key ID or fingerprint to sign with
    - passphrase (str): Passphrase for the signing key
    - clearsign (bool): Create clear-text signature (default: True)
    - detach (bool): Create detached signature
    - binary (bool): Create binary signature
    - extra_args (list): Additional GPG arguments
    
    Returns:
    Sign: Result object with signed data and signature information
    """

def sign_file(self, fileobj_or_path, keyid=None, passphrase=None, 
              clearsign=True, detach=False, binary=False, output=None, 
              extra_args=None):
    """
    Sign a file or file-like object.
    
    Parameters:
    - fileobj_or_path (str|file): File path or file-like object to sign
    - keyid (str): Key ID to sign with
    - passphrase (str): Passphrase for the signing key
    - clearsign (bool): Create clear-text signature
    - detach (bool): Create detached signature file
    - binary (bool): Create binary signature
    - output (str): Output file path for signature
    - extra_args (list): Additional GPG arguments
    
    Returns:
    Sign: Result object with signing status and signature data
    """

Signature Verification

Verify digital signatures to confirm data integrity and authenticity with comprehensive verification information.

def verify(self, data, **kwargs):
    """
    Verify signature on data string.
    
    Parameters:
    - data (str): Signed data to verify
    - extra_args (list): Additional GPG arguments
    
    Returns:
    Verify: Result object with verification status and signer information
    """

def verify_file(self, fileobj_or_path, data_filename=None, 
                close_file=True, extra_args=None):
    """
    Verify signature on a file.
    
    Parameters:
    - fileobj_or_path (str|file): File path or file-like object with signature
    - data_filename (str): Path to data file (for detached signatures)
    - close_file (bool): Whether to close file after verification
    - extra_args (list): Additional GPG arguments
    
    Returns:
    Verify: Result object with verification details
    """

def verify_data(self, sig_filename, data, extra_args=None):
    """
    Verify detached signature against data in memory.
    
    Parameters:
    - sig_filename (str): Path to detached signature file
    - data (str): Data to verify against signature
    - extra_args (list): Additional GPG arguments
    
    Returns:
    Verify: Result object with verification status
    """

Result Types

class Sign(StatusHandler):
    type: str              # Signature type ('signature', 'clearsign', 'detached')
    data: str              # Signed data (for clear-text and attached signatures)
    fingerprint: str       # Signing key fingerprint
    timestamp: str         # Signature timestamp
    what: str              # What was signed
    hash_algo: str         # Hash algorithm used
    
class Verify(StatusHandler):
    valid: bool            # True if signature is valid
    fingerprint: str       # Signer's key fingerprint
    signature_id: str      # Unique signature identifier
    username: str          # Signer's user ID
    key_id: str           # Signing key ID
    trust_level: int      # Trust level (0-4)
    trust_text: str       # Human-readable trust level
    creation_date: str    # Signature creation date
    sig_timestamp: str    # Signature timestamp
    expire_timestamp: str # Signature expiration
    pubkey_fingerprint: str # Public key fingerprint
    
    # Additional verification details
    key_status: str       # Key status ('GOODSIG', 'BADSIG', 'ERRSIG', etc.)
    summary: int          # Summary flags
    status: str           # Verification status message

Usage Examples

Basic Signing

import gnupg

gpg = gnupg.GPG()

# Clear-text signing (readable text with signature)
message = "This document needs to be signed for authenticity."
signed = gpg.sign(message, 
                 keyid='signer@example.com',
                 passphrase='signing_passphrase')

if signed.status == 'signature created':
    print("Signing successful")
    print(str(signed))  # Clear-text signed message
else:
    print(f"Signing failed: {signed.status}")

Detached Signatures

# Create detached signature (signature in separate data)
message = "Important document content"
signature = gpg.sign(message,
                    keyid='signer@example.com',
                    passphrase='signing_passphrase',
                    detach=True,
                    clearsign=False)

print("Original message:", message)
print("Detached signature:", str(signature))

# Verify detached signature
# (message and signature are separate)
verified = gpg.verify_data(signature, message)

File Signing

# Sign a file with clear-text signature
result = gpg.sign_file(
    '/path/to/document.txt',
    keyid='signer@example.com',
    passphrase='signing_passphrase',
    output='/path/to/document.txt.asc'
)

# Create detached signature file
result = gpg.sign_file(
    '/path/to/document.pdf',
    keyid='signer@example.com', 
    passphrase='signing_passphrase',
    detach=True,
    output='/path/to/document.pdf.sig'
)

# Binary signature
result = gpg.sign_file(
    '/path/to/data.bin',
    keyid='signer@example.com',
    passphrase='signing_passphrase',
    binary=True,
    output='/path/to/data.bin.gpg'
)

Signature Verification

# Verify clear-text signed message
signed_message = """-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

This is the message content.
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEE...
-----END PGP SIGNATURE-----"""

verified = gpg.verify(signed_message)

if verified.valid:
    print("Signature is valid!")
    print(f"Signed by: {verified.username}")
    print(f"Key fingerprint: {verified.fingerprint}")
    print(f"Created: {verified.creation_date}")
    print(f"Trust level: {verified.trust_text}")
else:
    print(f"Signature verification failed: {verified.status}")

Advanced Verification

# Verify file signature
result = gpg.verify_file('/path/to/signed_document.asc')

if result.valid:
    print("File signature valid")
    print(f"Signer: {result.username}")
    print(f"Key ID: {result.key_id}")
    print(f"Trust: {result.trust_text}")
    
    # Check trust level programmatically
    if result.trust_level >= 3:  # Marginal trust or better
        print("Signer is trusted")
    else:
        print("Warning: Signer trust level is low")
else:
    print(f"Invalid signature: {result.status}")

# Verify detached signature against data file
data_verified = gpg.verify_data(
    '/path/to/document.pdf.sig',  # Signature file
    open('/path/to/document.pdf', 'rb').read()  # Original data
)

Comprehensive Verification Example

def verify_document(gpg_instance, signed_data):
    """Comprehensive document verification with detailed reporting."""
    
    result = gpg_instance.verify(signed_data)
    
    verification_report = {
        'valid': result.valid,
        'signer': result.username,
        'fingerprint': result.fingerprint,
        'created': result.creation_date,
        'trust_level': result.trust_level,
        'trust_text': result.trust_text,
        'key_status': result.key_status,
        'warnings': []
    }
    
    # Analyze verification results
    if not result.valid:
        verification_report['warnings'].append(f"Invalid signature: {result.status}")
        return verification_report
    
    # Check trust level
    if result.trust_level < 2:
        verification_report['warnings'].append("Signer has very low trust level")
    elif result.trust_level < 3:
        verification_report['warnings'].append("Signer has low trust level")
    
    # Check key status
    if result.key_status == 'EXPKEYSIG':
        verification_report['warnings'].append("Signature made with expired key")
    elif result.key_status == 'REVKEYSIG':
        verification_report['warnings'].append("Signature made with revoked key")
    
    # Check signature age (example: warn if older than 1 year)
    from datetime import datetime, timedelta
    try:
        sig_date = datetime.strptime(result.creation_date, '%Y-%m-%d')
        if datetime.now() - sig_date > timedelta(days=365):
            verification_report['warnings'].append("Signature is over 1 year old")
    except:
        pass  # Date parsing failed
    
    return verification_report

# Usage
report = verify_document(gpg, signed_message)
print(f"Valid: {report['valid']}")
print(f"Signer: {report['signer']}")
for warning in report['warnings']:
    print(f"Warning: {warning}")

Multiple Signature Handling

# Some messages may have multiple signatures
# Each signature is verified independently

def verify_all_signatures(gpg_instance, multi_signed_data):
    """Handle data with potentially multiple signatures."""
    
    results = []
    
    # GPG will verify all signatures in the data
    result = gpg_instance.verify(multi_signed_data)
    
    # Process primary signature
    if hasattr(result, 'signature_id'):
        results.append({
            'valid': result.valid,
            'signer': result.username,
            'fingerprint': result.fingerprint,
            'signature_id': result.signature_id
        })
    
    # Note: For multiple signatures, you may need to parse
    # the GPG output or use additional verification calls
    
    return results

Error Handling and Troubleshooting

def robust_verify(gpg_instance, signed_data):
    """Robust verification with comprehensive error handling."""
    
    try:
        result = gpg_instance.verify(signed_data)
        
        if result.valid:
            return {
                'status': 'valid',
                'signer': result.username,
                'fingerprint': result.fingerprint,
                'trust': result.trust_text
            }
        else:
            # Analyze why verification failed
            if 'no public key' in result.status.lower():
                return {
                    'status': 'missing_key',
                    'message': 'Public key not in keyring',
                    'key_id': getattr(result, 'key_id', 'unknown')
                }
            elif 'bad signature' in result.status.lower():
                return {
                    'status': 'bad_signature', 
                    'message': 'Signature does not match data'
                }
            else:
                return {
                    'status': 'verification_failed',
                    'message': result.status,
                    'stderr': result.stderr
                }
                
    except Exception as e:
        return {
            'status': 'error',
            'message': f'Verification error: {str(e)}'
        }

# Usage with error handling
verification_result = robust_verify(gpg, signed_document)

if verification_result['status'] == 'valid':
    print(f"Valid signature from {verification_result['signer']}")
elif verification_result['status'] == 'missing_key':
    print(f"Need to import key: {verification_result['key_id']}")
else:
    print(f"Verification issue: {verification_result['message']}")