I'm testing Silvertunnel-NG lib. I want to have a server that accepts connections and a client in the same application.

At this moment, I'm trying to connect to my own hidden service created by Silvertunnel-NG lib. I can do it, but my hostname change in every execution. I can connect but first I have to create a new hidden service, I can't use an onion address created in other execution.

This is my test code:

public static void setHiddenService(File dir, TorNetLayerUtil tNLU) throws IOException {
    // Create new private+public hidden service key
    TorHiddenServicePrivateNetAddress tHSPNA = tNLU.createNewTorHiddenServicePrivateNetAddress();

    // write new private+public hidden service key to directory
    tNLU.writeTorHiddenServicePrivateNetAddressToFiles(dir, tHSPNA);

public static TorHiddenServicePortPrivateNetAddress readHiddenService(File dir, TorNetLayerUtil tNLU, int port) throws IOException {
    TorHiddenServicePrivateNetAddress netAddress = tNLU.readTorHiddenServicePrivateNetAddressFromFiles(dir, true);
    return new TorHiddenServicePortPrivateNetAddress(netAddress, port);

public static void setUp() {
    System.setProperty(TorConfig.SYSTEMPROPERTY_TOR_MINIMUM_ROUTE_LENGTH, "2");
    System.setProperty(TorConfig.SYSTEMPROPERTY_TOR_MAXIMUM_ROUTE_LENGTH, "2");
    System.setProperty(TorConfig.SYSTEMPROPERTY_TOR_MINIMUM_IDLE_CIRCUITS, "2");

public static void main(String[] args) throws IOException {

    setUp(); // setup TOR for tests

    TorNetLayerUtil tNLU = TorNetLayerUtil.getInstance();
    File dir = new File("/key/"); // directory of hostname file
    setHiddenService(dir, tNLU); // create a new hidden service

    TorHiddenServicePortPrivateNetAddress netAddress = readHiddenService(dir, tNLU, 80);

    // get TorNetLayer instance and wait until it is ready
    NetLayer netLayer = NetFactory.getInstance().getNetLayerById(NetLayerIDs.TOR);

    TorNetServerSocket netServerSocket = (TorNetServerSocket) netLayer.createNetServerSocket(null, netAddress);


If i comment "setHiddenService(dir, tNLU);" there are a connection problem, because my hostname have changed.

Can someone tell me what is going on?

Lib: Silvertunnel-NG 0.0.4.

Update: I have created a new method to get hidden service from a private_key file.

public static TorHiddenServicePrivateNetAddress createHiddenServiceFromPrivKey(File pkfile, TorNetLayerUtil tNLU) throws IOException{
    final String privateKeyPEMStr = FileUtil.readFile(pkfile);
    final TorHiddenServicePrivateNetAddress netAddressWithoutPort = tNLU.parseTorHiddenServicePrivateNetAddressFromStrings(privateKeyPEMStr, null, false);

    return netAddressWithoutPort;

Update: I recommend to use Stem (Python based) in order to control TOR. Works better.

  • Just to throwing this out there, that library has some serious problems. For example, it doesn't appear to use Entry Guards (I don't know java that well but from my reading of how it builds circuits that's what it looks like), which makes you far more vulnerable to anyone trying to deanonymize Tor users. For reference of why they're important: blog.torproject.org/blog/…
    – cacahuatl
    Commented Jun 28, 2016 at 22:16

1 Answer 1


You need to supply a pre-generated key for your hidden service, or it will be considered as an ephimerial, i.e. it exists only until restart. This is the default behaviour, so if you want to have a static hidden service name - no problem! Pre-generate your key and supply it as an argument to your code for creating the service: it's an optional argument in the call.

  • Oh! Didn't see that parameter. Thanks for the answer. I will try it.
    – WDay
    Commented Jun 28, 2016 at 18:09
  • I'm sorry but I don't see where I have to put this parameter. The method "createNewTorHiddenServicePrivateNetAddress" don't have any parameters. When I use "readHiddenService" I get exactly what I want, but it's seems like hidden service don't start. I get "java.io.IOException: connectToHiddenService(): couldn't connect to an introduction point of ..." error.
    – WDay
    Commented Jun 28, 2016 at 19:06
  • @WDay actually, it's in the Tor control protocol specification ADD_ONION method.
    – Alexey Vesnin
    Commented Jun 28, 2016 at 19:15
  • It looks like this library acts as Tor, it's not using ADD_ONION or interfacing with the control port. It's a java OR/OP implementation.
    – cacahuatl
    Commented Jun 28, 2016 at 22:34
  • @WDay you better try to generate a key file using tor binary and load it explicitly in your code. This I have understood from the docs. Please try it and let's see if it works
    – Alexey Vesnin
    Commented Jun 29, 2016 at 16:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .