Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

QuickStart Tor in .NET Core

4.96/5 (18 votes)
21 Aug 2021MIT3 min read 38.3K  
How to use Tor in .NET Core

Introduction

At the time of writing, there is no Tor library that supports .NET Core. I needed one for one of my projects I am working on, called NTumbleBit, so I had to create it myself. It is not a full featured library, but rather a lean, robust one. Only implements essential Tor features.

  • I want to make anonymous requests.
  • I want to make requests to onion APIs.

These are the most common use cases that lead someone to use Tor inside their application. This library aims to serve these basic needs and nothing more. 

Image 1

Understanding the Problem

Why we even need to use a third party library for Tor.

Quote:

Some people attempt to launch the Tor process on their local machine, giving the process a port number for the SOCKS port, and then configure their browser to point to the Tor process. This will not work.

Tor is a SOCKS proxy which means that it is able to connect to IP addresses and ports, but it does not understand HTTP requests.

(Source)

Configure Tor

  1. Download Tor Expert Bundle
  2. Download the torrc config file sample
  3. Place torrc in the proper default location (depending on your OS) and edit it:
    • Optionally uncomment and edit the SocksPort, if you don't uncomment, it will default to 9050 port anyway
    • The default ControlPort in the sample is 9051, optionally edit it.
    • Modify the password hash
      • To run my tests, for the ControlPortPassword = "ILoveBitcoin21" the hash should be: HashedControlPassword 16:0978DBAF70EEB5C46063F3F6FD8CBC7A86DF70D2206916C1E2AE29EAF6
      • For your application, you should use different one, a more complicated one. Then start tor like this: tor --hash-password password where password is the password you've chosen. It will give you the HashedControlPassword.
  4. Start tor, it will listen to the ports you set in the config file.

SocksPort vs ControlPort

Quote:

The control port is used for controlling Tor, usually via other software like Arm. The Socks port is the port running as a SOCKS5 proxy. This is the one you want to use. Please note that Tor is not an HTTP proxy, so your script will need to be configured to use a SOCKS5 proxy.

(Source)

Build & Test

If you are in a hurry, you can skip this section and just get the NuGet package and use it. Now get .NET Core, if you haven't already done so and fire up a terminal:

  1. git clone https://github.com/nopara73/DotNetTor
  2. cd DotNetTor/
  3. dotnet restore
  4. cd src/DotNetTor.Tests/
  5. dotnet test

How to Use It

Consider the following simple console app, where:

  1. I write out your real IP
  2. Your Tor IP
  3. Change your Tor circuit
  4. Finally, write out the changed Tor IP.
var requestUri = "http://icanhazip.com/";

// 1. Get real IP
using (var httpClient = new HttpClient())
{
    var message = httpClient.GetAsync(requestUri).Result;
    var content = message.Content.ReadAsStringAsync().Result;
    Console.WriteLine($"Your real IP: \t\t{content}");
}

// 2. Get Tor IP
using (var httpClient = new HttpClient(new SocksPortHandler("127.0.0.1", socksPort: 9050)))
{
    var message = httpClient.GetAsync(requestUri).Result;
    var content = message.Content.ReadAsStringAsync().Result;
    Console.WriteLine($"Your Tor IP: \t\t{content}");

    // 3. Change Tor IP
    var controlPortClient = new ControlPort.Client
        ("127.0.0.1", controlPort: 9051, password: "ILoveBitcoin21");
    controlPortClient.ChangeCircuitAsync().Wait();

    // 4. Get changed Tor IP
    message = httpClient.GetAsync(requestUri).Result;
    content = message.Content.ReadAsStringAsync().Result;
    Console.WriteLine($"Your other Tor IP: \t{content}");
}

Conclusion

While I did not provide a full-featured Tor library, but rather a minimal one, without any external dependency, I know I covered the most popular needs in a platform (.NET Core) where there is nothing else available at the time of writing.

Acknowledgements

  • Originally, the SocksPort part of this project was a leaned down, modified and .NET Core ported version of the SocketToMe project.
  • Originally, the ControlPort part of this project was a leaned down, modified and .NET Core ported version of the Tor.NET project.
  • At this point of the development, you can still find parts of the former project in the codebase, however the latter has been completely replaced.

Updates

  • 24th January, 2017
    • Version 2.1 is out
    • Limitations are removed
    • You can request different addresses within the same `HttpClient`
  • 19th January, 2017
    • Version 2.0 is out
    • Simplified usage
    • Not breaking old userspace
    • Async support
    • Bug fixes
    • Performance increase
  • 27th December, 2016
    • Fix torrc sample reference link
    • Fix some typo and formatting mistake
    • Add updates section
    • Change licence to MIT

License

This article, along with any associated source code and files, is licensed under The MIT License