Generate A Vanity .onion Address For Your Tor Hidden Service Using Scallion
Ever wonder how Tor sites get those custom vanity .onion addresses such as silkroada7bc3kld.onion? These addresses can be generated by hidden service operators for production use, and are just as secure as the automatically generated (and often more cryptic) addresses.
Hidden service .onion addresses are really just the public part of a key pair. Utilizing asymmetric encryption, a hidden service uses the public key (a 16 character string that functions as the actual address prefix) and a private key (a much longer string that is known only to the hidden service) to verify the identity of the service. Anyone connecting to the public key can only do so if the hidden service has access to the private key. Under normal circumstances, only the service operator has access to that private key, so you could trust that the address has not been hijacked.
Keep in mind, while it takes a long time, it is possible for someone to generate the same keypair as another hidden service. While computationally expensive, entities able to throw enough resources at generating an identical address would be able to do so much more quickly than someone acting alone on a sole machine.
Generation with Scallion
Scallion is one tool that can be used for generation. Unlike previous tools for generation addresses, Scallion focuses on GPUs, meaning it works much faster than CPU-targeting utilities in most cases. In my experience, Scallion does not work on ARM devices (Use Shallot or Eschalot instead), but if you have an x86_64 processor and some sort of video graphics (integrated or otherwise), you should be good to go.
Let’s get started generating custom .onion addresses. I will assume that you have access to a Linux machine and are familiar with the terminal. I will be using Debian, but this guide should be easy to modify for most distributions.
First, install some dependencies and then clone Scallion onto your machine:
$ sudo apt install clinfo mono-complete mono-devel nvidia-opencl-common nvidia-opencl-dev nvidia-opencl-icd libssl1.0-dev beignet beignet-dev ocl-icd-opencl-dev ocl-icd-libopencl1
$ git clone https://github.com/lachesis/scallion.git
Now, we will move to the scallion directory, and build the scallion
executable:
$ cd scallion
$ xbuild scallion.sln /p:TargetFrameworkVersion="v4.5"
Next, we will get a list of all of the devices that can be used for generating addresses:
$ mono scallion/bin/Debug/scallion.exe -l
Id:0 Name:Intel(R) HD Graphics Skylake Desktop GT2
PreferredGroupSizeMultiple:16 ComputeUnits:24 ClockFrequency:1000
MaxConstantBufferSize:134217728 MaxConstantArgs:8 MaxMemAllocSize:3221225472
We can see I have one device with an identifier that I can target. You may have more than one device.
Now we can use Scallion to find an address that starts with a word or phrase of our choice. Let’s start Scallion with 8 threads, and have it use device ``. We will look for addresses that start with “apple”. After a little waiting, you should get some similar output with the .onion address (public key) and the private key:
$ mono scallion/bin/Debug/scallion.exe -t8 -d 0 apple
Cooking up some delicious scallions...
Using kernel optimized from file kernel.cl (Optimized4)
Using work group size 16
Compiling kernel... done.
Testing SHA1 hash...
CPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
GPU SHA-1: d3486ae9136e7856bc42212385ea797094475802
Looks good!
LoopIteration:1 HashCount:16.78MH Speed:98.7MH/s Runtime:00:00:00 Predicted:00:00:00 Found new key! Found 1 unique keys.
2018-01-03T00:24:24.645322Z
applencoaipu4tqj.onion
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQCcDTg3+pON2oUclpStVlFVhtcpleNwtmdO3ZVuN2cPe9tyATjH
fye++edUSTwVm6EZZABrK3iSBdGAITXxRpc5dBM+SHPals6DEECRffa+d2QazJq2
xjhU7sfocXMzly+lALtE3T/I8yhFwcDlv/LGsWn6P9Hh2A2otDz3SCeGCQIEXGYD
DwKBgBkW9kDgDFafPvLhA0YIaDei5tBR5gJXt2vqabJfbi8P7RKF3GJ6vlHXu7xS
XikDmN5lJ+dAeFH5mH4mx0TAyfpjHvwrvCcVFPuXnt8ufDHYnRc5B8hYg/bpe0eS
9iZpSFKvq1Io49Wlt04KKAW86Nk0EJRPlkU6ewfOvs5AHI9vAkEAz+N847csHbcx
79RlBhvoT+GUYoSdKvtB+0pyv4mRYEV3SHFATVwXlTksOcPkI1dFVftkoXaEEld2
RTmsVlaLNQJBAMAqnKx+s4LAj2NxzBTpbcpeVY+DauWBoNMUo5Qdqm3SSV4hPsbd
Bf99XvCWS+7tD+jhks4mffOcKQZNK4JHVgUCQQDH6n4Uf2QWhZHvnY0niHE0ydiu
f2KIBc2spzWzcCWiyBqmtAbjhT3/HajJHB3zYdzHPrI0uVFHVqrjBnhRKSVjAkEA
vWUSQ9u4jPBH/z3ahdD6kbvQA90Jxo/JQgrwaHAUrli/SvmOC3xx/kSWLVPSlSk4
p96zeIgMolOS4Tfiff+newJAUaCQumLZori7RCT+2XOXFCoV03TLlujS8L+2sNH1
LPR8Brc3CBv+ZlleYnJCR4J88py8dFGYSYM95qmpCek1SA==
-----END RSA PRIVATE KEY-----
After generating a private key and address, you will want to use them with your Tor hidden service. The private key and address usually sit in files within the /var/lib/tor/hidden_service/
directory and are named hostname
and private_key
respectively.
For a full list of options and flags, we can run the scallion
executable with the --help
flag:
$ mono scallion/bin/Debug/scallion.exe --help
Usage: scallion [OPTIONS]+ regex [regex]+
Searches for a tor hidden service address that matches one of the provided regexes.
Options:
-k, --keysize=VALUE Specifies keysize for the RSA key
-n, --nonoptimized Runs non-optimized kernel
-l, --listdevices Lists the devices that can be used.
-h, -?, --help Displays command line usage help.
--gpg GPG vanitygen mode.
-d, --device=VALUE Specifies the opencl device that should be used.
-g, --groupsize=VALUE Specifies the number of threads in a workgroup.
-w, --worksize=VALUE Specifies the number of hashes preformed at one
time.
-t, --cputhreads=VALUE Specifies the number of CPU threads to use when
creating work. (EXPERIMENTAL - OpenSSL not
thread-safe)
-p, --save-kernel=VALUE Saves the generated kernel to this path.
-o, --output=VALUE Saves the generated key(s) and address(es) to this
path.
--skip-sha-test Skip the SHA-1 test at startup.
--quit-after=VALUE Quit after this many keys have been found.
--timestamp=VALUE Use this value as a timestamp for the RSA key.
-c, --continue Continue to search for keys rather than exiting
when a key is found.
--command=VALUE When a match is found specified external program
is called with key passed to stdin.
Example: "--command 'tee example.txt'" would
save the key to example.txt
If the command returns with a non-zero exit code,
the program will return the same code.