github.com/Carcraftz/utls@v0.0.0-20220413235215-6b7c52fd78b6/README.upstream.md (about)

     1  # ![uTLS](logo_small.png) uTLS
     2  [![Build Status](https://travis-ci.org/refraction-networking/utls.svg?branch=master)](https://travis-ci.org/refraction-networking/utls)
     3  [![godoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/refraction-networking/utls#UConn)
     4  ---
     5  uTLS is a fork of "crypto/tls", which provides ClientHello fingerprinting resistance, low-level access to handshake, fake session tickets and some other features. Handshake is still performed by "crypto/tls", this library merely changes ClientHello part of it and provides low-level access.  
     6  Golang 1.11+ is required.  
     7  If you have any questions, bug reports or contributions, you are welcome to publish those on GitHub. If you want to do so in private, you can contact one of developers personally via sergey.frolov@colorado.edu
     8  
     9  Documentation below may not keep up with all the changes and new features at all times,
    10  so you are encouraged to use [godoc](https://godoc.org/github.com/refraction-networking/utls#UConn).
    11  
    12  # Features
    13  ## Low-level access to handshake
    14  * Read/write access to all bits of client hello message.  
    15  * Read access to fields of ClientHandshakeState, which, among other things, includes ServerHello and MasterSecret.
    16  * Read keystream. Can be used, for example, to "write" something in ciphertext.
    17  
    18  ## ClientHello fingerprinting resistance
    19  Golang's ClientHello has a very unique fingerprint, which especially sticks out on mobile clients,
    20  where Golang is not too popular yet.
    21  Some members of anti-censorship community are concerned that their tools could be trivially blocked based on
    22  ClientHello with relatively small collateral damage. There are multiple solutions to this issue.
    23  
    24  **It is highly recommended to use multiple fingeprints, including randomized ones to avoid relying on a single fingerprint.**
    25  [utls.Roller](#roller) does this automatically.
    26  
    27  ### Randomized Fingerprint
    28  Randomized Fingerprints are supposedly good at defeating blacklists, since
    29  those fingerprints have random ciphersuites and extensions in random order.
    30  Note that all used ciphersuites and extensions are fully supported by uTLS,
    31  which provides a solid moving target without any compatibility or parrot-is-dead attack risks.  
    32  
    33  But note that there's a small chance that generated fingerprint won't work,
    34  so you may want to keep generating until a working one is found,
    35  and then keep reusing the working fingerprint to avoid suspicious behavior of constantly changing fingerprints.
    36  [utls.Roller](#roller) reuses working fingerprint automatically.
    37  
    38  #### Generating randomized fingerprints
    39  
    40  To generate a randomized fingerprint, simply do:
    41  ```Golang
    42  uTlsConn := tls.UClient(tcpConn, &config, tls.HelloRandomized)
    43  ```
    44  you can use `helloRandomizedALPN` or `helloRandomizedNoALPN` to ensure presence or absence of
    45  ALPN(Application-Layer Protocol Negotiation) extension.
    46  It is recommended, but certainly not required to include ALPN (or use helloRandomized which may or may not include ALPN).
    47  If you do use ALPN, you will want to correctly handle potential application layer protocols (likely h2 or http/1.1).
    48  
    49  #### Reusing randomized fingerprint
    50  ```Golang
    51  // oldConn is an old connection that worked before, so we want to reuse it
    52  // newConn is a new connection we'd like to establish
    53  newConn := tls.UClient(tcpConn, &config, oldConn.ClientHelloID)
    54  ```
    55  
    56  ### Parroting
    57  This package can be used to parrot ClientHello of popular browsers.
    58  There are some caveats to this parroting:
    59  * We are forced to offer ciphersuites and tls extensions that are not supported by crypto/tls.
    60  This is not a problem, if you fully control the server and turn unsupported things off on server side.
    61  * Parroting could be imperfect, and there is no parroting beyond ClientHello.
    62  #### Compatibility risks of available parrots
    63  
    64  | Parrot        | Ciphers* | Signature* | Unsupported extensions | TLS Fingerprint ID              |
    65  | ------------- | -------- | ---------- | ---------------------- | --------------------------------------------- |
    66  | Chrome 62     | no       | no         | ChannelID              | [0a4a74aeebd1bb66](https://tlsfingerprint.io/id/0a4a74aeebd1bb66) |
    67  | Chrome 70     | no       | no         | ChannelID, Encrypted Certs | [bc4c7e42f4961cd7](https://tlsfingerprint.io/id/bc4c7e42f4961cd7) |
    68  | Chrome 72     | no       | no         | ChannelID, Encrypted Certs | [bbf04e5f1881f506](https://tlsfingerprint.io/id/bbf04e5f1881f506) |
    69  | Chrome 83     | no       | no         | ChannelID, Encrypted Certs | [9c673fd64a32c8dc](https://tlsfingerprint.io/id/9c673fd64a32c8dc) |
    70  | Firefox 56    | very low | no         | None                   | [c884bad7f40bee56](https://tlsfingerprint.io/id/c884bad7f40bee56) |
    71  | Firefox 65    | very low | no         | MaxRecordSize                   | [6bfedc5d5c740d58](https://tlsfingerprint.io/id/6bfedc5d5c740d58) |
    72  | iOS 11.1      | low** | no         | None                   | [71a81bafd58e1301](https://tlsfingerprint.io/id/71a81bafd58e1301) |
    73  | iOS 12.1      | low** | no         | None                   | [ec55e5b4136c7949](https://tlsfingerprint.io/id/ec55e5b4136c7949) |
    74  
    75  \* Denotes very rough guesstimate of likelihood that unsupported things will get echoed back by the server in the wild,
    76  *visibly breaking the connection*.  
    77  \*\* No risk, if `utls.EnableWeakCiphers()` is called prior to using it.  
    78  
    79  #### Parrots FAQ
    80  > Does it really look like, say, Google Chrome with all the [GREASE](https://tools.ietf.org/html/draft-davidben-tls-grease-01) and stuff?
    81  
    82  It LGTM, but please open up Wireshark and check. If you see something — [say something](issues).
    83  
    84  > Aren't there side channels? Everybody knows that the ~~bird is a word~~[parrot is dead](https://people.cs.umass.edu/~amir/papers/parrot.pdf)
    85  
    86  There sure are. If you found one that approaches practicality at line speed — [please tell us](issues).
    87  
    88  However, there is a difference between this sort of parroting and techniques like SkypeMorth.
    89  Namely, TLS is highly standardized protocol, therefore simply not that many subtle things in TLS protocol
    90  could be different and/or suddenly change in one of mimicked implementation(potentially undermining the mimicry).
    91  It is possible that we have a distinguisher right now, but amount of those potential distinguishers is limited.
    92  
    93  ### Custom Handshake
    94  It is possible to create custom handshake by
    95  1) Use `HelloCustom` as an argument for `UClient()` to get empty config
    96  2) Fill tls header fields: UConn.Hello.{Random, CipherSuites, CompressionMethods}, if needed, or stick to defaults.
    97  3) Configure and add various [TLS Extensions](u_tls_extensions.go) to UConn.Extensions: they will be marshaled in order.
    98  4) Set Session and SessionCache, as needed.
    99  
   100  If you need to manually control all the bytes on the wire(certainly not recommended!),
   101  you can set UConn.HandshakeStateBuilt = true, and marshal clientHello into UConn.HandshakeState.Hello.raw yourself.
   102  In this case you will be responsible for modifying other parts of Config and ClientHelloMsg to reflect your setup
   103  and not confuse "crypto/tls", which will be processing response from server.
   104  
   105  ## Roller
   106  
   107  A simple wrapper, that allows to easily use multiple latest(auto-updated) fingerprints.
   108  
   109  ```Golang
   110  // NewRoller creates Roller object with default range of HelloIDs to cycle
   111  // through until a working/unblocked one is found.
   112  func NewRoller() (*Roller, error)
   113  ```
   114  
   115  ```Golang
   116  // Dial attempts to connect to given address using different HelloIDs.
   117  // If a working HelloID is found, it is used again for subsequent Dials.
   118  // If tcp connection fails or all HelloIDs are tried, returns with last error.
   119  //
   120  // Usage examples:
   121  //
   122  // Dial("tcp4", "google.com:443", "google.com")
   123  // Dial("tcp", "10.23.144.22:443", "mywebserver.org")
   124  func (c *Roller) Dial(network, addr, serverName string) (*UConn, error)
   125  ```
   126  
   127  ## Fake Session Tickets
   128  Fake session tickets is a very nifty trick that allows power users to hide parts of handshake, which may have some very fingerprintable features of handshake, and saves 1 RTT.
   129  Currently, there is a simple function to set session ticket to any desired state:
   130  
   131  ```Golang
   132  // If you want you session tickets to be reused - use same cache on following connections
   133  func (uconn *UConn) SetSessionState(session *ClientSessionState)
   134  ```
   135  
   136  Note that session tickets (fake ones or otherwise) are not reused.  
   137  To reuse tickets, create a shared cache and set it on current and further configs:
   138  
   139  ```Golang
   140  // If you want you session tickets to be reused - use same cache on following connections
   141  func (uconn *UConn) SetSessionCache(cache ClientSessionCache)
   142  ```
   143  
   144  # Client Hello IDs
   145  See full list of `clientHelloID` values [here](https://godoc.org/github.com/refraction-networking/utls#ClientHelloID).  
   146  There are different behaviors you can get, depending  on your `clientHelloID`:
   147  
   148  1. ```utls.HelloRandomized``` adds/reorders extensions, ciphersuites, etc. randomly.  
   149  `HelloRandomized` adds ALPN in a percentage of cases, you may want to use `HelloRandomizedALPN` or
   150  `HelloRandomizedNoALPN` to choose specific behavior explicitly, as ALPN might affect application layer.
   151  2. ```utls.HelloGolang```
   152      HelloGolang will use default "crypto/tls" handshake marshaling codepath, which WILL
   153      overwrite your changes to Hello(Config, Session are fine).
   154      You might want to call BuildHandshakeState() before applying any changes.
   155      UConn.Extensions will be completely ignored.
   156  3. ```utls.HelloCustom```
   157  will prepare ClientHello with empty uconn.Extensions so you can fill it with TLSExtension's manually.
   158  4. The rest will will parrot given browser. Such parrots include, for example:
   159  	* `utls.HelloChrome_Auto`- parrots recommended(usually latest) Google Chrome version
   160  	* `utls.HelloChrome_58` - parrots Google Chrome 58
   161  	* `utls.HelloFirefox_Auto` - parrots recommended(usually latest) Firefox version
   162  	* `utls.HelloFirefox_55` - parrots Firefox 55
   163  	
   164  # Usage
   165  ## Examples
   166  Find basic examples [here](examples/examples.go).  
   167  Here's a more [advanced example](https://github.com/sergeyfrolov/gotapdance/blob//9a777f35a04b0c4c5dacd30bca0e9224eb737b5e/tapdance/conn_raw.go#L275-L292) showing how to generate randomized ClientHello, modify generated ciphersuites a bit, and proceed with the handshake.
   168  ### Migrating from "crypto/tls"
   169  Here's how default "crypto/tls" is typically used:
   170  ```Golang
   171      dialConn, err := net.Dial("tcp", "172.217.11.46:443")
   172      if err != nil {
   173          fmt.Printf("net.Dial() failed: %+v\n", err)
   174          return
   175      }
   176  
   177      config := tls.Config{ServerName: "www.google.com"}
   178      tlsConn := tls.Client(dialConn, &config)
   179      n, err = tlsConn.Write("Hello, World!")
   180      //...
   181  ```
   182  To start using using uTLS:
   183  1. Import this library (e.g. `import tls "github.com/refraction-networking/utls"`)
   184  2. Pick the [Client Hello ID](#client-hello-ids)
   185  3. Simply substitute `tlsConn := tls.Client(dialConn, &config)`
   186  with `tlsConn := tls.UClient(dialConn, &config, tls.clientHelloID)`  
   187  
   188  ### Customizing handshake
   189  Some customizations(such as setting session ticket/clientHello) have easy-to-use functions for them. The idea is to make common manipulations easy:
   190  ```Golang
   191      cRandom := []byte{100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
   192          110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
   193          120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
   194          130, 131}
   195      tlsConn.SetClientRandom(cRandom)
   196      masterSecret := make([]byte, 48)
   197      copy(masterSecret, []byte("masterSecret is NOT sent over the wire")) // you may use it for real security
   198  
   199      // Create a session ticket that wasn't actually issued by the server.
   200      sessionState := utls.MakeClientSessionState(sessionTicket, uint16(tls.VersionTLS12),
   201          tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
   202          masterSecret,
   203          nil, nil)
   204      tlsConn.SetSessionState(sessionState)
   205  ```
   206  
   207  For other customizations there are following functions
   208  ```
   209  // you can use this to build the state manually and change it
   210  // for example use Randomized ClientHello, and add more extensions
   211  func (uconn *UConn) BuildHandshakeState() error
   212  ```
   213  ```
   214  // Then apply the changes and marshal final bytes, which will be sent
   215  func (uconn *UConn) MarshalClientHello() error
   216  ```
   217  
   218  ## Contributors' guide
   219  Please refer to [this document](./CONTRIBUTORS_GUIDE.md) if you're interested in internals
   220  
   221  ## Credits
   222  The initial development of uTLS was completed during an internship at [Google Jigsaw](https://jigsaw.google.com/). This is not an official Google product.