lexiforest / curl_cffi

Python binding for curl-impersonate fork via cffi. A http client that can impersonate browser tls/ja3/http2 fingerprints.
https://curl-cffi.readthedocs.io/
MIT License
2.42k stars 261 forks source link

Customized impersonating fingerprints #194

Closed T-256 closed 4 months ago

T-256 commented 10 months ago

Is your feature request related to a problem? Please describe. Yes, I think for solving https://github.com/yifeikong/curl_cffi/issues/169 we need python level fingerprint generator.

Describe the solution you'd like Ability to create impersonation in python level and use it in requests.

Describe alternatives you've considered python-tls-client example

perklet commented 10 months ago

We need to get a list of customizable fields.

For TLS, there are too many, I have not bothered to collect them implementation is on the way.

For http2, we are almost there, only one part is missing everything is there.

All the options are listed here: https://github.com/yifeikong/curl-impersonate#libcurl-impersonate

We also need to implement a python class like ImpersonateSpec to specify the detailed instructions.

perklet commented 10 months ago

The first step is to be able to impersonate Firefox with BoringSSL.

These issues need to be resolved at boringssl level.

This issue can be fixed at curl level.

After the above issues are fixed, we need to

perklet commented 4 months ago

Added in v0.7.0b7, examples.

T-256 commented 4 months ago

I wished a base class that we could inherited browsers and change some of its parameters. Actually, I wish to have customizations same as files in https://github.com/yifeikong/curl-impersonate/blob/main/chrome directly in python.

class BaseFingerprint:
    @property
    def property_name(self): ...

class Chrome124(BaseFingerprint):
    """
    # Updates in this version since Chrome123:
    - Added X25519Kyber768 support
    - Added Priority header support
    """

    def __init__(self):
        self._ciphers ="TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,ECDHE-ECDSA-AES128-GCM-SHA256,ECDHE-RSA-AES128-GCM-SHA256,ECDHE-ECDSA-AES256-GCM-SHA384,ECDHE-RSA-AES256-GCM-SHA384,ECDHE-ECDSA-CHACHA20-POLY1305,ECDHE-RSA-CHACHA20-POLY1305,ECDHE-RSA-AES128-SHA,ECDHE-RSA-AES256-SHA,AES128-GCM-SHA256,AES256-GCM-SHA384,AES128-SHA,AES256-SHA"
        self._curves = "X25519Kyber768Draft00:X25519:P-256:P-384"

    @property
    def ciphers(self):
        return self._ciphers

    @property
    def curves(self):
        return self._curves
perklet commented 4 months ago

It's my first thought, too.

However, since the fingerprints for browsers have been built into C, I don't feel it necessary to have an exact clone on Python side. If it was designed from ground up with python bindings in mind, I would have the browser settings in Python, too.

Nonetheless, the most common usecase for customized fingerprints should be impersonating other http libs, e.g. okhttp. The easist way to get their fingerprints for users is to copy the JA3 string from WireShark or somewhere.

If your usecase is to alter the browsers' fingerprints a little bit, you can simply add a curl setopt option using the curl_options parameter.