Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ltfc.net auth_key problem #277

Open
poorfish opened this issue Mar 4, 2025 · 1 comment
Open

ltfc.net auth_key problem #277

poorfish opened this issue Mar 4, 2025 · 1 comment

Comments

@poorfish
Copy link

poorfish commented Mar 4, 2025

Previously(#128), this website used URL signing, but now they have increased the difficulty by using an auth_key like .../18/22_2.jpg?auth_key=1741087702-0-0-b68ca3011ed9325b69f12e24ecc9ccaf. How can I download the painting under this situation? Thank you.

Sample:
https://ltfc.net/view/SUHA/674887cb078ca419ca0a62e4

@lovasoa
Copy link
Owner

lovasoa commented Mar 4, 2025

I have reversed their signature scheme, in case anyone is interested to implement it in dezoomify

def sign_aliyun_url(url):
    m = re.match(r'^(https*:\/\/[\w\-\.]*)(\/.*\.(jpeg|jpg|png))\?*(.*)$', url)
    domain, path, _, query = m.groups()
    query_str = f"{query}&" if query else ''
    timestamp = int(time.time())
    signature = hashlib.md5(f"{path}-{timestamp}-0-0-ltfcdotnet".encode()).hexdigest()
    
    return f"{domain}{path}?{query_str}auth_key={timestamp}-0-0-{signature}"

small test script

"""
URL Authentication Module

This module provides functionality to sign URLs for secure access to resources.
It implements two different signing methods:
1. Aliyun OSS authentication - Uses a timestamp and custom signature
2. CAG authentication - Uses a different signature format

The module detects which authentication method to use based on the URL pattern
and the specified source type.
"""

import re
import time
import hashlib
from urllib.parse import quote


def sign_url(url, source_type):
    """
    Main function to sign a URL based on the source type

    Args:
        url (str): The URL to be signed
        source_type (str): The source type, e.g., "TILES_SOURCE_ALIYUN"

    Returns:
        str: The signed URL
    """
    if source_type == "TILES_SOURCE_ALIYUN":
        return sign_aliyun_url(url)
    else:
        return sign_cag_url(url)


def sign_aliyun_url(url):
    """
    Signs a URL using Aliyun OSS authentication method

    Args:
        url (str): The URL to sign

    Returns:
        str: The signed URL
    """
    if not url:
        return url
    
    aliyun_url_pattern = r'^(https*:\/\/[\w\-\.]*)(\/.*\.(jpeg|jpg|png))\?*(.*)$'
    matches = re.match(aliyun_url_pattern, url)
    
    if not matches:
        return url
    
    domain = matches.group(1)
    path = matches.group(2)
    query_params = matches.group(4) or ''
    
    query_string = f"{query_params}&" if query_params else ''
    timestamp = int(time.time())
    nonce1 = 0
    nonce2 = 0

    auth_key = generate_auth_key(path, timestamp, nonce1, nonce2)
    signature = hashlib.md5(auth_key.encode()).hexdigest()
    
    return f"{domain}{path}?{query_string}auth_key={timestamp}-{nonce1}-{nonce2}-{signature}"


def generate_auth_key(path, timestamp, nonce1, nonce2):
    """
    Generates the authentication key for Aliyun URL signing

    Args:
        path (str): The URL path
        timestamp (int): Current timestamp
        nonce1 (int): First nonce value
        nonce2 (int): Second nonce value

    Returns:
        str: The authentication key
    """
    return f"{path}-{timestamp}-{nonce1}-{nonce2}-ltfcdotnet"


def sign_cag_url(url):
    """
    Signs a URL using CAG authentication method

    Args:
        url (str): The URL to sign

    Returns:
        str: The signed URL
    """
    cag_url_pattern = r'^(http.*\/\/[^\/]*)(\/.*\.(jpg|jpeg))\?*(.*)$'
    matches = re.match(cag_url_pattern, url)
    
    if not matches:
        return url
    
    domain = matches.group(1)
    path = matches.group(2)
    query_params = matches.group(4) or ''
    
    secret_key = "b49b4d8a45b8f098ba881d98abbb5c892f8b5c98"
    timestamp = format(int(time.time() // 31536000 * 31536000), 'x')
    sign_string = secret_key + quote(path) + timestamp
    signature = hashlib.md5(sign_string.encode()).hexdigest()
    
    return f"{domain}{path}?{query_params}&sign={signature}&t={timestamp}"


def main():
    """
    Main function to handle command line arguments and sign URLs
    """
    import argparse
    parser = argparse.ArgumentParser(description='Sign URLs for secure access to resources')
    parser.add_argument('url', help='The URL to sign')
    args = parser.parse_args()
    
    # Auto-detect source type if requested
    source_type = "TILES_SOURCE_CAG"
    aliyun_keywords = ['aliyun', 'oss', 'cagstore']
    lower_url = args.url.lower()
    if any(keyword in lower_url for keyword in aliyun_keywords):
        source_type = "TILES_SOURCE_ALIYUN"
    
    # Sign the URL
    signed_url = sign_url(args.url, source_type)
    
    # Print the result
    print(signed_url)


if __name__ == "__main__":
    main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants