👻 uTLS: prizrak-utls
uTLS is the library that makes the TLS fingerprint (ClientHello) look like a real browser. It decides which browser a connection looks like for client-fingerprint and REALITY.
mihomo uses metacubex/utls v1.8.8. Prizrak-Core uses its own fork legiz-ru/prizrak-utls (branch v1.9.0-mod-meta-mldsa-chr155). It consists of three parts:
- Base: the metacubex
v1.9.0-mod-metabranch. It is a newer line than v1.8.8 in mihomo and carries all metacubex changes. - Up-to-date upstream refraction-networking/utls: sync with
crypto/tlsfrom Go 1.27.1, the Chrome 155 fingerprint, fixes for compressed certificate decompression, GREASE and PSK fixes, MLKEM1024 key exchange. The fork still builds with Go 1.20. - REALITY ML-DSA-65: see REALITY.
- Key shares after the first: the keys of every classical key share are kept, so a server may select any of them (backport of refraction-networking/utls#416, as in Jolymmiles/utls).
Which browser client-fingerprint means
Section titled “Which browser client-fingerprint means”client-fingerprint | mihomo | Prizrak-Core |
|---|---|---|
chrome | Chrome 133 | Chrome 155 |
firefox | Firefox 120 | Firefox 148 |
safari | Safari 16.0 | Safari 26.3 |
ios, android, edge, 360, qq | unchanged | unchanged |
In Prizrak-Core the firefox and safari fingerprints also carry the post-quantum X25519MLKEM768 key exchange, as real browsers of these versions do. In mihomo only chrome has it.
randomized, random and Firefox against P-256
Section titled “randomized, random and Firefox against P-256”randomizedalways offersX25519MLKEM768with its key share. uTLS drew twice and independently whether to offer the group and whether to send its key share. Some processes sent the group without the key share: REALITY turned them away, and a server preferring the post-quantum exchange answered with a HelloRetryRequest uTLS could not follow. Some sent the key share without the group, which OpenSSL rejects. Now the hello always offers both and sends key shares forX25519MLKEM768andX25519only, as Chrome does, the same fix as in Jolymmiles/Xray-core.randomno longer picksios.ios(iOS 14) sends noX25519MLKEM768, and Xray’s REALITY servers turn such a hello away, sorandomfailed against them on some starts. It now pickschrome,safariorfirefox.firefoxagainst servers that select P-256. Firefox fingerprints send key shares forX25519andP-256, and uTLS kept the key of the first only: a server that selected P-256 failed the handshake withtls: invalid server key share. The key of every share is now kept (part 4 above). The ClientHello is unchanged.