uTLS—Fork of the Go standard TLS library, providing low-level access to the ClientHello for mimicry purposes

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.


Low-level access to handshake

  • Read/write access to all bits of client hello message.
  • Read access to fields of ClientHandshakeState, which, among other things, includes ServerHello and MasterSecret.
  • Read keystream. Can be used, for example, to “write” something in ciphertext.

ClientHello fingerprinting resistance

Golang’s ClientHello has a very unique fingerprint, which especially sticks out on mobile clients, where Golang is not too popular yet. Some members of anti-censorship community are concerned that their tools could be trivially blocked based on ClientHello with relatively small collateral damage. There are multiple solutions to this issue.

Randomized Fingerprint

Randomized Fingerprints are supposedly good at defeating blacklists, since those fingerprints have random ciphersuites and extensions in random order. Note that all used ciphersuites and extensions are fully supported by uTLS, which provides a solid moving target without any compatibility or parrot-is-dead attack risks.

Fake Session Tickets

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.

The author, @_sf, told me that uTLS allows very low-level ClientHello access, so it could be used for censorship circumvention is some cases.

So, uTLS has a bunch of built-in mimicry ClientHelloSpec’s, for example, HelloChrome_62, which includes all the information that uTLS needs to marshal a Chrome-like ClientHello, such as ciphers and extensions. Let’s say you want to send a huge ClientHello by including an extension with ID someID and a 16KB body. You can copy-paste the generation function for that spec or any other ClientHelloSpec (uTLS also supports generation of randomized ClientHellos), then add your utls.GenericExtension{Id: someID, Data: make([]byte, 1024*16)} to a desired place in the ordered list of ClientHelloSpec.Extensions, and apply the resulting spec with uconn.ApplyPreset() function.

The “fake SNI in the beginning and real SNI before/after padding” may require a roundabout implementation: I try to prevent users from shooting themselves in the foot, and including 2 SNI extensions with different values is precisely one of the things I wouldn’t want to happen accidentally. However, I believe you still should be able to do that: just include second SNI extension as utls.GenericExtension{}, so uTLS doesn’t recognize the the type of the second SNI extension, and simply marshals it as-is.

Hi I’m new here.
So my ISP is throttling my internet speed except for one site i use that site as a fake sni i did v2ray it works fine full speed but using v2ray need a server and i don’t want to use different ip so i just want to know if this tool will work for me i don’t know how to use it if you can help me appreciate it Thank you

I don’t think uTLS helps in your situation. It’s only useful if your ISP is interfering with connections based on the TLS fingerprint. If the ISP is only looking at SNI, it’s possible to change the SNI without using uTLS.

uTLS is not a tool or proxy to use directly. It’s more like a library that other tools can import and use.

On the BBS forum there are some recent threads about how TLS fingerprinting is used in Iran and China, and how uTLS can help: