【问题标题】:ZeroMQ C# Ironhouse exampleZeroMQ C# Ironhouse 示例
【发布时间】:2021-07-29 17:52:12
【问题描述】:

我是 ZeroMQ 的新手,我一直在比较使用 ZeroMQ NuGet 包和 NetMQNetMQ 安全 NuGet 包的消息安全性.

到目前为止,我还没有找到使用 Curve Security 的 Ironhouse 示例的 C# 版本。 ZGuides repo 上有一个“待办事项”项目,但到目前为止还没有实施。 (https://github.com/metadings/zguide/issues/1)

我还试图确定 NetMQ.Security 安全方法是否比 ZeroMQ 4 中内置的曲线安全方法更好。似乎有关 Curve 的大多数信息至少来自 2014 年或更早。

任何信息将不胜感激!

【问题讨论】:

  • " 似乎有关 Curve 的大多数信息至少来自 2014 年或更早。" - 那我可以检查一下它是否仍然受支持/活跃?
  • @BrianBehm 您是否介意明确说明您计划收集和使用哪些功能以及它们各自的指标以“确定”哪些“安全方法优于”其他?如果没有任何明确的衡量标准,这样的比较似乎不可能被严格表达、以价值为重点并基于证据记录。 提前感谢您添加规则。
  • @user3666197,“更好”可能是用错词。我知道 ZeroMQ 已经实现了 CurveZMQ 并且 clrzmq4 绑定似乎已经实现了这一点。 NetMQ 似乎选择了不同的方法,不支持 CurveZMQ。所以也许更好的问题是,“CurveZMQ 是否已经失宠,因此 NetMQ 采用的方法是否更受欢迎?”。理想情况下,我真的在寻找一些在 C# 中实现 CurveZMQ 的工作 C# 代码,这样我就可以自己进行比较,这就是我添加赏金的原因。希望这能回答您的问题。
  • @BrianBehm 实际上不,它没有。但这可能是由于我的想象力有限——试图想象另一个词——一个增强的人类是什么样子的?我只是试图理解简单易懂的事情,并且不知何故无法想象一个增强型人类的交付实际上是如何发生的 [_ 看来我确实太老了,无法理解一切:o)_]。 顺便说一句: 还看到了您关于 ZeroMQ 的另一篇文章——在向 S/O 询问有关碰撞曲线的方式之前,您是否制作了一个普通(非曲线)PUB/SUB 进行通信作案手法?
  • @user3666197,我已经能够让代码适用于非曲线实现。我相信这将是 NULL 安全方法。如果我没记错的话,PLAIN 需要一个我没有尝试过的用户名/密码,因为它不适合我的应用程序的实际用例。在我的示例代码中,如果您注释掉与设置曲线键选项有关的几行,则通信就像冠军一样工作。

标签: c# zeromq


【解决方案1】:

发布者和订阅者都需要使用自己的一组公钥\私钥。在您的订阅者示例代码中,您设置了CurvePublicKey(设置为服务器的,这是错误的但仍然存在)但不设置CurveSecretKey - 这就是为什么您会得到“无法打开客户端启动担保”的原因。这是您从另一个已解决的问题中获得的示例:

public class Program
{
    static void Main(string[] args) {
        using (var context = new ZContext()) {
            Console.WriteLine($"Curve Supported: {ZeroMQ.ZContext.Has("curve")}");
            byte[] serverPublicKey;
            byte[] serverSecretKey;
            Z85.CurveKeypair(out serverPublicKey, out serverSecretKey);

            var publisher = new ZSocket(context, ZSocketType.PUB);
            publisher.CurvePublicKey = serverPublicKey;
            publisher.CurveSecretKey = serverSecretKey;
            publisher.CurveServer = true;
            publisher.Bind("tcp://*:5050");

            var subscriber = new ZSocket(context, ZSocketType.SUB);
            byte[] subPublicKey;
            byte[] subSecretKey;
            Z85.CurveKeypair(out subPublicKey, out subSecretKey);
            subscriber.CurvePublicKey = subPublicKey;
            subscriber.CurveSecretKey = subSecretKey;
            subscriber.CurveServerKey = serverPublicKey;
            ZError connectError;
            subscriber.Connect("tcp://mybox:5050", out connectError);
            if (connectError != null) {
                Console.WriteLine($"Connection error: {connectError.Name} - {connectError.Number} - {connectError.Text}");
            }
            subscriber.SubscribeAll();

            // Publish some messages
            Task.Run(() => {
                for (var i = 1; i <= 5; i++) {
                    var msg = $"Pub msg: {Guid.NewGuid().ToString()}";
                    using (var frame = new ZFrame(msg)) {
                        publisher.Send(frame);
                    }
                }
            });
            Task.Run(() => {
                // Receive some messages
                while (true) {
                    using (var frame = subscriber.ReceiveFrame()) {
                        var msg = frame.ReadString();
                        Console.WriteLine($"Received: {msg}");
                    }
                }
            });
            Console.WriteLine("Press ENTER to exit");
            Console.ReadLine();
            ZError subError;
            subscriber.Disconnect("tcp://mybox:5050", out subError);
            subscriber.Dispose();
            ZError pubError;
            publisher.Disconnect("tcp://*:5050", out pubError);
            publisher.Dispose();
        }
    }
}

【讨论】:

  • 我尚未验证此代码,但看起来很棒。不过你是对的,我缺少的是客户端和服务器有自己的密钥对这一事实。我会给你奖励积分。
  • Evk,如果您想在我的其他问题上发布此示例,我也会将您的示例标记为那里的答案。 stackoverflow.com/questions/46944949/…
  • @BrianBehm 不鼓励复制粘贴答案,所以我关闭了这个问题作为这个问题的重复。
【解决方案2】:

确实,NetMQ 的 C# 示例并不多。我发现这个工作“CurveTests.cs”:

    public void CurveTest()
    {
        var serverPair = new NetMQCertificate();
        using var server = new DealerSocket();
        server.Options.CurveServer = true;
        server.Options.CurveCertificate = serverPair;
        server.Bind($"tcp://127.0.0.1:55367");
        
        var clientPair = new NetMQCertificate();
        using var client = new DealerSocket();
        client.Options.CurveServerKey = serverPair.PublicKey;
        client.Options.CurveCertificate = clientPair;
        client.Connect("tcp://127.0.0.1:55367");

        for (int i = 0; i < 100; i++)
        {
            client.SendFrame("Hello");
            var hello = server.ReceiveFrameString();
            Assert.Equal("Hello", hello);
            
            server.SendFrame("World");
            var world = client.ReceiveFrameString();
            Assert.Equal("World", world);
        }
    }

重要提示 - 如果您想在不同应用程序之间共享服务器公钥,请不要使用字符串表示 (serverPair.PublicKeyZ85),因为加密不起作用。我认为它与编码有关。更好地将字节数组表示保存到某个文件并共享它:

File.WriteAllBytes("serverPublicKey.txt", serverPair.PublicKey);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2011-05-28
    相关资源
    最近更新 更多