C# 使用 Tor 作为代理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1962483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:13:58  来源:igfitidea点击:

using Tor as Proxy

c#proxyhttpwebrequesttor

提问by Lay

I'm trying to use Tor-Server as a proxy in HttpWebRequest, my code looks like this:

我正在尝试使用 Tor-Server 作为 中的代理HttpWebRequest,我的代码如下所示:

HttpWebRequest request;
HttpWebResponse response;

request = (HttpWebRequest)WebRequest.Create("http://www.google.com");
request.Proxy = new WebProxy("127.0.0.1:9051");

response = (HttpWebResponse)request.GetResponse();
response.Close();

it works perfect with "normal" proxies but with Tor I'm getting Exceptions while calling

它与“普通”代理完美配合,但使用 Tor 我在调用时遇到异常

GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"

GetResponse() with Status = ServerProtocolViolation. The message is (in German...):Message = "Der Server hat eine Protokollverletzung ausgeführt.. Section=ResponseStatusLine"

回答by Mehrdad Afshari

Tor is notan HTTP proxy. It's a SOCKS proxy. You can use an HTTP proxy that supports forwarding on SOCKS (like Privoxy) and connect to that via code instead.

Tor不是HTTP 代理。这是一个 SOCKS 代理。您可以使用支持在 SOCKS 上转发的 HTTP 代理(如 Privoxy)并通过代码连接到该代理。

回答by jspcal

Yes like the other poster said, a socks client is needed. Some libraries are Starksoft Proxy, ProxySocketand ComponentSpace Socks Proxy. sockscapis a tool that intercepts and reroutes winsock calls, and privoxyis a local proxy that can tunnel your requests over socks. A couple different solutions.

是的,就像另一张海报说的那样,需要一个袜子客户端。一些库是Starksoft ProxyProxySocketComponentSpace Socks Proxysockscap是一个拦截和重新路由 winsock 调用的工具,privoxy是一个本地代理,可以通过socks 传输您的请求。几个不同的解决方案。

回答by Christopher Tarquini

If you have privoxyinstalled and running you can do

如果您安装并运行了privoxy,您可以执行以下操作

request.Proxy = new WebProxy("127.0.0.1:8118"); // default privoxy port

Which will enable you to make requests using tor

这将使您能够使用 tor 发出请求

回答by Fernando Reis Guimaraes

You need "extract" a stream from socks...

你需要从袜子中“提取”一个流......

Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Runtime.CompilerServices

Public Class Form1

    Sub Form1_Load() Handles Me.Load

        Dim Host As String = "google.com"

        Dim P As New SocksProxy("localhost", 64129) 'Set your socks proxy here
        Dim Stream As NetworkStream = P.GetStream(Host, 80)
        Dim buffer As Byte() = Download(Stream, Host, "")

        My.Computer.FileSystem.WriteAllBytes("C:\webpage.html", buffer, False)

        MsgBox("ok")
    End Sub

    Function Download(Stream As NetworkStream, Host As String, Resource As String) As Byte()

        Using writer = New StreamWriter(Stream)
            writer.Write(String.Format("GET /{2} HTTP/1.1{0}Host: {1}{0}{0}", vbCrLf, Host, Resource))
            writer.Flush()

            Dim byteList As New List(Of Byte)
            Dim bufferSize As Integer = 4096
            Dim buffer(bufferSize - 1) As Byte

            Do
                Dim bytesRead As Integer = Stream.Read(buffer, 0, bufferSize)
                byteList.AddRange(buffer.Take(bytesRead))
            Loop While Stream.DataAvailable

            Return byteList.ToArray
        End Using

    End Function
End Class


Public Class SocksProxy

    Private _SocksHost As String
    Private _SocksPort As Integer

    Sub New(SocksHost As String, SocksPort As Integer)
        _SocksHost = SocksHost
        _SocksPort = SocksPort
    End Sub

    Function GetStream(HostDest As String, PortDest As Short) As NetworkStream

        Dim client As TcpClient = New TcpClient()
        client.Connect(_SocksHost, _SocksPort)

        Dim stream As NetworkStream = client.GetStream()
        'Auth
        Dim buf = New Byte(299) {}
        buf(0) = &H5
        buf(1) = &H1
        buf(2) = &H0
        stream.Write(buf, 0, 3)

        ReadExactSize(stream, buf, 0, 2)
        If buf(0) <> &H5 Then
            Throw New IOException("Invalid Socks Version")
        End If
        If buf(1) = &HFF Then
            Throw New IOException("Socks Server does not support no-auth")
        End If
        If buf(1) <> &H0 Then
            Throw New Exception("Socks Server did choose bogus auth")
        End If

        buf(0) = &H5
        buf(1) = &H1
        buf(2) = &H0
        buf(3) = &H3
        Dim domain = Encoding.ASCII.GetBytes(HostDest)
        buf(4) = CByte(domain.Length)
        Array.Copy(domain, 0, buf, 5, domain.Length)
        Dim port = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(CShort(PortDest)))
        buf(5 + domain.Length) = port(0)
        buf(6 + domain.Length) = port(1)
        stream.Write(buf, 0, domain.Length + 7)


        ' Reply
        ReadExactSize(stream, buf, 0, 4)
        If buf(0) <> &H5 Then
            Throw New IOException("Invalid Socks Version")
        End If
        If buf(1) <> &H0 Then
            Throw New IOException(String.Format("Socks Error {0:X}", buf(1)))
        End If
        Dim rdest = String.Empty
        Select Case buf(3)
            Case &H1
                ' IPv4
                ReadExactSize(stream, buf, 0, 4)
                Dim v4 = BitConverter.ToUInt32(buf, 0)
                rdest = New IPAddress(v4).ToString()
                Exit Select
            Case &H3
                ' Domain name
                ReadExactSize(stream, buf, 0, 1)
                If buf(0) = &HFF Then
                    Throw New IOException("Invalid Domain Name")
                End If
                ReadExactSize(stream, buf, 1, buf(0))
                rdest = Encoding.ASCII.GetString(buf, 1, buf(0))
                Exit Select
            Case &H4
                ' IPv6
                Dim octets = New Byte(15) {}
                ReadExactSize(stream, octets, 0, 16)
                rdest = New IPAddress(octets).ToString()
                Exit Select
            Case Else
                Throw New IOException("Invalid Address type")
        End Select
        ReadExactSize(stream, buf, 0, 2)
        Dim rport = CUShort(IPAddress.NetworkToHostOrder(CShort(BitConverter.ToUInt16(buf, 0))))

        Return stream
    End Function

    Private Sub ReadExactSize(stream As NetworkStream, buffer As Byte(), offset As Integer, size As Integer)
        While size <> 0
            Dim read = stream.Read(buffer, offset, size)
            If read < 0 Then
                Throw New IOException("Premature end")
            End If
            size -= read
            offset += read
        End While
    End Sub

End Class

回答by Ogglas

Use the library "SocksWebProxy". You can use it with WebClient & WebRequest (Just assign a new SocksWebProxy to the *.Proxy attribute). No Need for Privoxy or similar service to translate http traffic to tor.

使用库“SocksWebProxy”。您可以将它与 WebClient 和 WebRequest 一起使用(只需为 *.Proxy 属性分配一个新的 SocksWebProxy)。无需 Privoxy 或类似服务将 http 流量转换为 Tor。

https://github.com/Ogglas/SocksWebProxy

https://github.com/Ogglas/SocksWebProxy

I made some extensions to it as well by enabling the control port. Here is how you could have Tor running in the background without Tor Browser Bundle started and to control Tor we can use Telnet or send commands programmatically via Socket.

我还通过启用控制端口对其进行了一些扩展。下面是如何在没有 Tor 浏览器包启动的情况下让 Tor 在后台运行,并且为了控制 Tor,我们可以使用 Telnet 或通过 Socket 以编程方式发送命令。

Socket server = null;

//Authenticate using control password
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9151);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Connect(endPoint);
server.Send(Encoding.ASCII.GetBytes("AUTHENTICATE \"your_password\"" + Environment.NewLine));
byte[] data = new byte[1024];
int receivedDataLength = server.Receive(data);
string stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);

//Request a new Identity
server.Send(Encoding.ASCII.GetBytes("SIGNAL NEWNYM" + Environment.NewLine));
data = new byte[1024];
receivedDataLength = server.Receive(data);
stringData = Encoding.ASCII.GetString(data, 0, receivedDataLength);
if (!stringData.Contains("250"))
{
    Console.WriteLine("Unable to signal new user to server.");
    server.Shutdown(SocketShutdown.Both);
    server.Close();
}
else
{
    Console.WriteLine("SIGNAL NEWNYM sent successfully");
}

Steps to configure Tor:

配置 Tor 的步骤:

  1. Copy torrc-defaults into the directory in which tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Data\Tor"
  2. Open a cmd prompt window
  3. chdir to the directory where tor.exe is. Default directory if you are using Tor browser is: "~\Tor Browser\Browser\TorBrowser\Tor\"
  4. Generate a password for Tor control port access. tor.exe --hash-password “your_password_without_hyphens” | more
  5. Add your password password hash to torrc-defaults under ControlPort 9151. It should look something like this: hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507. If you accept your password to be "password" you can copy the string above.
  6. You can now access Tor control via Telnet once it is started. Now the code can run, just edit the path to where your Tor files are located in the program. Test modifying Tor via Telnet:
  7. Start tor with the following command: tor.exe -f .\torrc-defaults
  8. Open up another cmd prompt and type: telnet localhost 9151
  9. If all goes well you should see a completely black screen. Type "autenticate “your_password_with_hyphens”" If all goes well you should see "250 OK".
  10. Type "SIGNAL NEWNYM" and you will get a new route, ergo new IP. If all goes well you should see "250 OK".
  11. Type "setevents circ" (circuit events) to enable console output
  12. Type "getinfo circuit-status" to see current circuits
  1. 将 torrc-defaults 复制到 tor.exe 所在的目录中。如果您使用 Tor 浏览器,则默认目录为:“~\Tor Browser\Browser\TorBrowser\Data\Tor”
  2. 打开一个 cmd 提示窗口
  3. chdir 到 tor.exe 所在的目录。如果您使用 Tor 浏览器,则默认目录为:“~\Tor Browser\Browser\TorBrowser\Tor\”
  4. 为 Tor 控制端口访问生成密码。 tor.exe --hash-password “your_password_without_hyphens” | more
  5. 您的密码,密码哈希加入的torrc,默认ControlPort 9151.下,它应该是这个样子:hashedControlPassword 16:3B7DA467B1C0D550602211995AE8D9352BF942AB04110B2552324B2507。如果您接受密码为“password”,则可以复制上面的字符串。
  6. 现在您可以通过 Telnet 启动 Tor 控制。现在代码可以运行了,只需编辑程序中 Tor 文件所在位置的路径。通过 Telnet 测试修改 Tor:
  7. 使用以下命令启动 tor: tor.exe -f .\torrc-defaults
  8. 打开另一个 cmd 提示符并键入: telnet localhost 9151
  9. 如果一切顺利,您应该会看到一个全黑的屏幕。输入“ autenticate “your_password_with_hyphens”” 如果一切顺利,您应该看到“250 OK”。
  10. 输入“ SIGNAL NEWNYM”,你会得到一个新的路由,也就是新的IP。如果一切顺利,您应该会看到“250 OK”。
  11. 输入“ setevents circ”(电路事件)以启用控制台输出
  12. 输入“ getinfo circuit-status”查看当前电路