Пример за ZeroMQ C# Ironhouse

Сравнително нов съм в ZeroMQ и сравнявам сигурността на съобщенията с помощта на пакета ZeroMQ NuGet и пакетите NetMQ & NetMQ Security NuGet.

Досега не успях да намеря C# версия на примера на Ironhouse, използвайки Curve Security. Има елемент "todo" в ZGuides repo, но досега нищо не е изпълнено. (https://github.com/metadings/zguide/issues/1)

Също така се опитвам да определя дали подходът NetMQ.Security към сигурността е по-добър от подхода за сигурност на кривата, който е вграден в ZeroMQ 4. Изглежда, че повечето информация за Curve е поне от 2014 г. или по-рано.

Всяка информация ще бъде много оценена!


person Brian Behm    schedule 13.10.2017    source източник
comment
Изглежда, че повечето информация за Curve е поне от 2014 г. или по-рано. - това може ли да проверя дали все още се поддържа/активен?   -  person Mitch Wheat    schedule 26.10.2017
comment
@BrianBehm Бихте ли предпочели да посочите изрично какви са вашите функции и какви са съответните им показатели, които планирате да съберете и използвате, за да определите кой подход към сигурността е по-добър< /b> от друго? Без никаква ясна метрика никое подобно сравнение не изглежда възможно да бъде строго изразено, да бъде фокусирано върху заслугите и да се основава на записи на доказателства. Благодарим предварително за добавянето на правилата.   -  person user3666197    schedule 26.10.2017
comment
@user3666197, по-добре може да е грешната дума за използване. Знам, че ZeroMQ е внедрил CurveZMQ и обвързването clrzmq4 изглежда е продължило това. NetMQ изглежда е избрал различен подход и не поддържа CurveZMQ. Така че може би по-добрият въпрос е CurveZMQ изпадна ли в немилост и следователно подходът, възприет от NetMQ, е предпочитан?. В идеалния случай наистина търся някакъв работещ C# код, който внедрява CurveZMQ в C#, за да мога да направя сравненията за себе си, поради което добавих наградата. Надяваме се, че това отговаря на въпроса ви.   -  person Brian Behm    schedule 26.10.2017
comment
@BrianBehm Всъщност не, не е така. Но това може да се дължи на ограниченото ми въображение -- опитвах се да си представя друга дума -- как изглежда увеличен човек? Просто се опитвам да разбера лесни и прости неща и някак си не мога да си представя как всъщност може да се осъществи доставката на увеличен човек [_ Наистина изглежда, че съм твърде стар, за да разбирам всичко :o) _]. BTW: също видях другата ви публикация за ZeroMQ -- направихте ли обикновен ( non-Curve'd ) PUB/SUB за комуникация, преди да попитате на S/O за сблъскващ се Curve'd modus operandi?   -  person user3666197    schedule 26.10.2017
comment
@user3666197, успях да накарам кода да работи за реализация без крива. Вярвам, че това би бил подходът за сигурност NULL. Ако си спомням правилно, PLAIN изисква потребителско име/парола, които не съм пробвал, тъй като не отговаря на реалния случай на употреба за моето приложение. В моя примерен код, ако коментирате няколкото реда, които са свързани с опциите за настройка на кривите ключове, комуникацията работи като шампион.   -  person Brian Behm    schedule 26.10.2017


Отговори (2)


И издателят, и абонатът трябва да използват собствен набор от публични\частни ключове. Във вашия примерен код за абонат задавате CurvePublicKey (на този на сървъра, което е грешно, но все пак), но не задавате CurveSecretKey - затова получавате "не може да отвори клиент INITIATE вауч". Ето вашата извадка от друг коригиран въпрос:

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();
        }
    }
}
person Evk    schedule 01.11.2017
comment
Все още не съм проверил този код, но изглежда страхотно. Вие сте прав обаче, нещото, което ми липсваше, беше фактът, че клиентът и сървърът имат свои собствени KeyPairs. Ще ви дам точките за награда. - person Brian Behm; 01.11.2017
comment
Evk, ако искаш да публикуваш този пример на другия ми въпрос, ще отбележа и твоя като отговор там. stackoverflow.com/questions/46944949/ - person Brian Behm; 09.11.2017
comment
@BrianBehm не се препоръчва копиране и поставяне на отговори, така че затворих този въпрос като дубликат на този. - person Evk; 09.11.2017

Наистина, няма много C# примери с NetMQ. Намерих това, което работи 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);
person uzrgm    schedule 29.07.2021