Exception while converting String to Byte array

60 Views Asked by At

I am using ssh.net to transfer files through SFTP protocol. I need to validate host key fingerprint as an extra layer of security. For that, I wrote a method to convert the string to byte array to compare as I saved the host key as string in my xml configuration and the SFTP client brings the host key as byte array.

using System;
using System.IO;
using System.Linq;
using System.Runtime.Remoting.Channels;
using FsLogger;
using Renci.SshNet;


namespace FsUtils.FileOperations
{
    public class FtpHandler
    {
        public string User { get; set; }

        public string Password { get; set; }

        public string Server { get; set; }


        public void UploadFileSftp(string sourceFile, string targetDir, string sshHostKeyFingerprint)
        {
            using (var client = new SftpClient(Server, User, Password))
            {
                client.HostKeyReceived += (sender, e) =>
                {
                    byte[] receivedFingerprint = e.FingerPrint;
                    byte[] providedFingerprint = StringToByteArray(sshHostKeyFingerprint);

                    e.CanTrust = receivedFingerprint.SequenceEqual(providedFingerprint);
                };
                try
                {
                    client.Connect();

                    if (client.IsConnected)
                    {
                        using (var fileStream = File.OpenRead(sourceFile))
                        {
                            client.UploadFile(fileStream, targetDir);
                        }
                    }
                    Logging.Info("File uploaded successfully");
                }
                catch (Exception ex)
                {
                    Logging.Error($"Exception occurred - {ex.Message}");
                }
                finally
                {
                    if (client.IsConnected)
                        client.Disconnect();
                }
            }
        }

        private byte[] StringToByteArray(string hex)
        {
            return Enumerable.Range(0, hex.Length)
                .Where(x => x % 2 == 0)
                .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                .ToArray();
        }
    }
}

And this is where Sftp uploader method gets called-

using FsLogger;
using FsUtils.FileOperations;
using System;
using System.IO;
using System.Reflection;

namespace FsFtpImport
{
    public class FtpImporter
    {
        public FtpImportConfig Config { get; set; }
        private FtpHandler ftpHandler;

        public void Start()
        {
            if (Config == null)
            {
                Logging.Info("Config not found (NULL)");
                return;
            }

            try
            {
                ftpHandler = new FtpHandler
                {
                    User = Config.FtpUser,
                    Password = Config.FtpPassword,
                    Server = Config.FtpServer,
                };

                foreach (FolderMapping folderMap in Config.FolderMappings)
                {
                    string[] files = Directory.GetFiles(folderMap.ClientDirectory);

                    foreach (string file in files)
                    {
                        Uploadfile(file, folderMap.FtpDirectory,Config.SshHostKeyFingerprint);
                    }
                }
            }
            catch (Exception ex)
            {
                Logging.Exception(ex, MethodBase.GetCurrentMethod().Name);
            }
        }

        private void Uploadfile(string file, string targetdir,string fingerprint)
        {
            try
            {
                switch (Config.Protocol)
                {
                    case FtpProtocol.Sftp:
                    {
                        this.ftpHandler.UploadFileSftp(file, targetdir,fingerprint);
                        break;
                    }
                    default:
                    {
                        Logging.Error("unknown protocol");
                        break;
                    }
                }

                if (Config.DeleteSourceFiles)
                    File.Delete(file);
            }
            catch (Exception ex)
            {
                Logging.Error($"Error uploading file {file}");
                Logging.Exception(ex, MethodBase.GetCurrentMethod().Name);
                Logging.Info("File skipped");
            }
        }
    }
}

Now the problem is while converting my string host key to byte array, it throws exception.

<![LOG[Failed: Exception occurred - Additional non-parsable characters are at the end of the string.]LOG]!>

I collected the host key from the knwon-hosts file and copied the key along with its encryption algorithm. It looks like this-

ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBP4cDyvxP/kbZ1XrPxxyMshbTtrY605xu5VL37uZt9mv7d2ZqD3TSWoEcUgHgtzGuRzkGTfDXdT9J=

How to validate the host key fingerprint without any issues? I greatly appreciate your kind help.

0

There are 0 best solutions below