Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C中通过TCP发送密码#_C#_.net_Networking_Telnet - Fatal编程技术网

C# 在C中通过TCP发送密码#

C# 在C中通过TCP发送密码#,c#,.net,networking,telnet,C#,.net,Networking,Telnet,我是一个没有实践经验的程序员,所以基本上还是新手 我正在做的是通过Telnet或TCP登录到设备上。我不是通过类型命令来控制设备,而是使用自定义表单应用程序通过预先编程的按钮来发送类型字符串命令。该设备是一个旧的编解码器。我的软件的目的是创建一个从PC使用的按钮控制器 我遇到的问题是,我的一些设备有密码保护,而有些没有(不同的固件)。这是无法改变的。密码保护让我陷入困境 我正在使用ASCII向设备发送数据 public void Write(string cmd) {

我是一个没有实践经验的程序员,所以基本上还是新手

我正在做的是通过Telnet或TCP登录到设备上。我不是通过类型命令来控制设备,而是使用自定义表单应用程序通过预先编程的按钮来发送类型字符串命令。该设备是一个旧的编解码器。我的软件的目的是创建一个从PC使用的按钮控制器

我遇到的问题是,我的一些设备有密码保护,而有些没有(不同的固件)。这是无法改变的。密码保护让我陷入困境

我正在使用ASCII向设备发送数据

public void Write(string cmd)
        {
            if (!tcpSocket.Connected) return;
            byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
            tcpSocket.GetStream().Write(buf, 0, buf.Length);
我一直在MD5上搜索,结果被卡住了。 我已经尝试通过在文本框中键入密码并启动write命令来发送密码。我还尝试发送在互联网上找到的这段代码的输出

public string EncodePassword(string originalPassword)
        {
            //Declarations
            Byte[] originalBytes;
            Byte[] encodedBytes;
            MD5 md5;

            //Instantiate MD5CryptoServiceProvider, get bytes for original password and compute hash (encoded password)
            md5 = new MD5CryptoServiceProvider();
            originalBytes = ASCIIEncoding.Default.GetBytes(originalPassword);
            encodedBytes = md5.ComputeHash(originalBytes);
            //Convert encoded bytes back to a 'readable' string
            return BitConverter.ToString(encodedBytes);                            
我甚至找到了另一条MD5行,它强制使用大写和小写。我不知道它是否不能工作,因为它仍在发送ASCII码的密码

我知道我的密码是正确的,因为我可以在windows中加载telnet并在那里正常登录。如果您能帮助该客户机通过服务器的身份验证,我们将不胜感激


恕我直言。由于我无法回复,我不得不编辑。我想我对MD5感到困惑。。。在阅读了回复后,我认为我的问题是ASCII码。我需要纯文本

好的,这就是我的初学者条纹闪耀的地方。这是我第一次尝试编程,涉及到任何类型的网络(如果还没有那么明显的话)。通过阅读回复,我认为我的第一个问题是ASCII码。我认为这是发送的,尽管这是纯文本。考虑到当我使用不需要密码登录的同一客户端连接到服务器时。。。ASCII代码工作得很好

所以,如果我要使用纯文本,那么我将如何发送纯文本而不是字节转换?假设我认为ASCII是发送纯文本的方式是错误的……我现在认为这是错误的

我添加了更多代码来帮助实现这一点

使用Windows telnet客户端时,设备会提示输入密码,当您在telnet中键入密码时,在登录后才会显示文本。登录后,立即显示所有键入内容

用于套接字的类主要是我在google上找到的带有一些小tweek的代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;

namespace STC_Control
{
    enum Verbs
    {
        WILL = 251,
        WONT = 252,
        DO = 253,
        DONT = 254,
        IAC = 255
    }

    enum Options
    {
        SGA = 3
    }

    class TelnetConnection
    {
        TcpClient tcpSocket;

        int TimeOutMs = 100;

        public TelnetConnection(string Hostname, int Port)
        {
            tcpSocket = new TcpClient(Hostname, Port);

        }

        public void WriteLine(string cmd)
        {
            Write(cmd + "\n");
        }

        public void Write(string cmd)
        {
            if (!tcpSocket.Connected) return;
            byte[] buf = System.Text.ASCIIEncoding.ASCII.GetBytes(cmd.Replace("\0xFF", "\0xFF\0xFF"));
            tcpSocket.GetStream().Write(buf, 0, buf.Length);
        }

        public string Read()
        {

            if (!tcpSocket.Connected) return null;

                StringBuilder sb = new StringBuilder();

                do
                {
                    ParseTelnet(sb);
                    System.Threading.Thread.Sleep(TimeOutMs);
                } while (tcpSocket.Available > 0);
                return sb.ToString();

        }

        public bool IsConnected
        {
            get { return tcpSocket.Connected; }
        }

        void ParseTelnet(StringBuilder sb)
        {
            while (tcpSocket.Available > 0)
            {
                int input = tcpSocket.GetStream().ReadByte();
                switch (input)
                {
                    case -1:
                        break;
                    case (int)Verbs.IAC:
                        // interpret as command
                        int inputverb = tcpSocket.GetStream().ReadByte();
                        if (inputverb == -1) break;
                        switch (inputverb)
                        {
                            case (int)Verbs.IAC:
                                //literal IAC = 255 escaped, so append char 255 to string
                                sb.Append(inputverb);
                                break;
                            case (int)Verbs.DO:
                            case (int)Verbs.DONT:
                            case (int)Verbs.WILL:
                            case (int)Verbs.WONT:
                                // reply to all commands with "WONT", unless it is SGA (suppres go ahead)
                                int inputoption = tcpSocket.GetStream().ReadByte();
                                if (inputoption == -1) break;
                                tcpSocket.GetStream().WriteByte((byte)Verbs.IAC);
                                if (inputoption == (int)Options.SGA)
                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WILL : (byte)Verbs.DO);
                                else
                                    tcpSocket.GetStream().WriteByte(inputverb == (int)Verbs.DO ? (byte)Verbs.WONT : (byte)Verbs.DONT);
                                tcpSocket.GetStream().WriteByte((byte)inputoption);
                                break;
                            default:
                                break;
                        }
                        break;
                    default:
                        sb.Append((char)input);
                        break;
                }
            }

        }
    }
}
然后是节目

public Form1()
        {
            InitializeComponent();
        }
        //declorations
        TelnetConnection tc;
        Int16 vl = 13;


        private void connect_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(roomBox.Text))
            {
                MessageBox.Show("Please enter a selection before continuing");


            }
            else
            {
                {
                    try
                    {
                        //Connects to the server
                        tc = new TelnetConnection(roomBox.Text, 23);
                        //Enables controls
                        panelAll.Enabled = true;
                    }
                    catch
                    {
                        MessageBox.Show("Server Unreachable. ");
                        panelAll.Enabled = false;
                        cState.Text = "Disconnected";
                    }

                }
            }

// Button to send login password Temp created to test login
public void p_Click(object sender, EventArgs e)
        {
            try
            {
              //sends text to server  
              tc.WriteLine("PASSWORD");

              //enables Buttons
              panelAll.Enabled = true;

              //displays return to textbox to verify login or disconnect
              rx.Text = (tc.Read());
            }
            catch
            {
                panelAll.Enabled = false;
                MessageBox.Show("Communication with device was lost.");
                cState.Text = "Disconnected";
            }
        }

------------------------------------------------------------------------------------------ 您的代码似乎有点不完整,无法给出完整的答案。如果可能,提供一个从程序中剥离出来的更完整的逻辑流。但从我能收集到的,这里有一些即时提示

  • 不要将MD5与加密混淆。它们是非常非常不同的东西(MD5是单向散列,而加密是双向编码)。这很可能是你头痛的根源。加密/哈希握手方法必须得到双方的同意。如果您试图使用MD5哈希密码登录到只接受纯文本密码的设备,则该设备将无法将其识别为有效密码。对于这种情况,你真的无能为力。。。必须是纯文本
  • 你假设密码是ASCII码?如果不是,ASCII转换就是坏消息。这可能不是一个根本问题,而是需要思考的问题 编辑:事实上。。。让我更深入一点,因为经过进一步思考,我大约90%确定这是你的问题(当然没有更多信息)

    处理仅支持纯文本密码的设备时的逻辑流程如下(其中C是客户机[you],S是服务器[Theme])

    当使用任何类型的散列时

    [C] Hash password (MD5, SHA1, etc)
    [C] Send password
    [S] Receive hash of password. Check against hashed password stored (or worse, hash of plain-text password stored). Respond good/bad
    
    加密连接时(当客户端和服务器知道它们都使用哪种加密时)

    加密连接时(客户端/服务器可能不一定支持相同的方法,但知道如何协商使用哪种方法)


    正如你所看到的,非常不同的方法。这些必须内置到通信设备(服务器)中才能成功进行协商。

    我认为,您最好的解决方案是下载OpenSSL包,将其安装到设备和表单应用程序上,然后使用API使用安全外壳连接而不是telnet发送设备命令


    这样,密钥管理就在你的应用程序之外,你可以使用预先编写的API在经过测试的代码中进行加密。

    我认为这不是编程问题。我相信这更多的是理解你的设备是如何工作的问题。它接受明文形式的密码,还是接受哈希或加密形式的密码

    您可以通过telnet提供密码这一事实表明密码是纯文本的,除非telnet协议提供了一些身份验证

    如果您能提供telnet窗口的屏幕截图,那就太好了。我们也许可以从那里得到一些提示


    我建议您提交纯文本密码,后跟\n新行字符。

    很抱歉,我还不能直接对您更改的帖子发表评论,但可以。。。我真的很确定,你不应该试图MD5散列你的密码。您的目标设备很可能不支持加密或哈希。因此,您必须以纯文本形式发送密码。你的逻辑似乎没有任何问题,但沟通的方式却不可用。试着不要散列你的数据,让我知道它是否有效。哦,ASCII不是你的问题。它只是一个7位的编码标准(对于邋遢的处理程序是8位),而为您转换它的类正在将文本剥离为7位的等价物,在您的例子中,这可能甚至不明显(因为大多数基本拉丁字符映射为AS)
    [C] Hash password (MD5, SHA1, etc)
    [C] Send password
    [S] Receive hash of password. Check against hashed password stored (or worse, hash of plain-text password stored). Respond good/bad
    
    [C] Garble-garble-garble (password encrypted)
    [S] Got it... and garble-garble-garble turns into whatever plain-text password. Checked it against local storage and .... garble-garble-garble (good/bad encrypted)
    
    [C] Which encryption methods do you support? Here's my list...
    [S] Oh, well, we both support these methods. Which do you want to use?
    [C] IDEA sounds good.
    [S] Sounds good to me too. Start using it.
    [C] Garble-garble-garble (password encrypted)
    [S] Got it... and garble-garble-garble turns into whatever plain-text password. Checked it against local storage and .... garble-garble-garble (good/bad encrypted)