Решение для шифрования WCF для App.config, доступное для просмотра клиенту? - PullRequest
1 голос
/ 13 мая 2009

У меня есть настольное приложение, которое содержит App.config (program.exe.config в выпуске) с четко видимыми элементами, которые определяют мои конечные точки WCF и реализацию WCF.

В идеале я хотел бы скрыть это от глаз пользователя, от простого взлома, просмотра и изменения.

Должен ли я: -

  1. Программно создайте и сохраните мои конечные точки WCF и конфигурацию привязки в коде. или;
  2. Реализовать некоторую схему защиты через App.config (если так, что, как), эффективно запутывая / шифруя эти элементы из публичного просмотра, но понятно из моего кода?

Я уже использую .NET Reactor, чтобы запутать и защитить свою программу от методов отражения.

Обновление 13 мая-09 3:32 по Гринвичу + 10 Хорошо, мне удалось зашифровать system.serviceModel, но затем он оказался непригодным для использования, когда приложение пошло к запуску, поскольку было сгенерировано исключение (System.TypeInitializationException: инициализатор типа для 'System.ServiceModel.DiagnosticUtility' вызвал исключение.)

  <system.serviceModel>
    <!-- [bindings] -->
    <bindings configProtectionProvider="DPAPIProtection">
      <EncryptedData>
        <CipherData>
          <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+...

Так что эта идея идет. Я либо откажусь от этой идеи, либо установлю свои конечные точки в коде, который стоит за шифрованием.

Никого больше не беспокоит их адрес конечной точки, четко видимый в конфигурации ???

Ответы [ 4 ]

4 голосов
/ 13 мая 2009

В идеале я хотел бы скрыть это от глаз пользователя, от простого взлома, просмотра и изменения.

Вы действительно не можете защитить от этого, потому что любой, кто хочет выяснить, что он делает, просто устанавливает точку останова в конструкторе класса Endpoint WCF, а затем нажимает «go». Никакое запутывание не поможет вам там.

3 голосов
/ 13 мая 2009

Защита от изменений легче, чем защита от просмотра.

Если вас беспокоят просто изменения / взломы, вы можете просто вычислить цифровую подпись на элементах XML, составляющих ваши неизменяемые настройки WCF, используя ваш открытый ключ. Если клиент что-то изменит, сигнал не будет совпадать.

Я не знаю хорошего способа защитить его от взгляда, на самом деле, потому что решительный человек сможет узнать, что вы делаете в WCF (как указывал предыдущий автор). Вы можете сделать это более сложным, но это не помешает кому-либо просматривать или изучать информацию.

UPDATE

Вам необходимо использовать свой собственный закрытый ключ RSA для подписи. Возможно, у вас уже есть пара ключей RSA. Если нет, вы можете сгенерировать пару ключей, один раз, чтобы сделать подпись. Вот так.

        int keySize = 1024; // you choose
        byte[] key = Keys.GenerateKeyPair(keySize);

        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider();
        rsaKey.ImportCspBlob(key);

Если у вас есть это, вы можете экспортировать и сохранить его. Для собственного использования, подписывая, вам нужен закрытый ключ. Для проверки приложения будут использовать открытый ключ. Вот как ты их получаешь.

        string PublicKeyXml = rsaKey.ToXmlString(false);
        string PrivateKeyXml = rsaKey.ToXmlString(true);

Храните их. Если вы когда-нибудь захотите снова что-то подписать, используя тот же закрытый ключ, получите RSA CSP с методом FromXmlString (), передавая PrivateKeyXml. Если вы хотите проверить, используйте FromXmlString (), передавая PublicKeyXml.

Как только у вас есть ключ и XML для подписи, вы можете сделать подпись. Это происходит только во время упаковки и развертывания, когда вы создаете и завершаете конфигурацию.

    // Sign an XML file. 
    // This document cannot be verified unless the verifying 
    // code has the key with which it was signed.
    public static void SignXml(System.Xml.XmlDocument Doc, RSA Key)
    {
        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a SignedXml object.
        System.Security.Cryptography.Xml.SignedXml signedXml = new SignedXml(Doc);

        // Add the key to the SignedXml document.
        signedXml.SigningKey = Key;

        // Create a reference to be signed.
        Reference reference = new Reference();
        reference.Uri = "";

        // Add an enveloped transformation to the reference.
        var env = new XmlDsigEnvelopedSignatureTransform();
        reference.AddTransform(env);

        // Add the reference to the SignedXml object.
        signedXml.AddReference(reference);

        // Compute the signature.
        signedXml.ComputeSignature();

        // Get the XML representation of the signature and save
        // it to an XmlElement object.
        XmlElement xmlDigitalSignature = signedXml.GetXml();

        // Append the element to the XML document.
        Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, true));
    }

Затем вставьте подписанный XML в app.config или в виде строки в приложении, или как угодно. Когда приложение запускается, вы проверяете подпись во время выполнения, используя блоб открытого ключа.

        // Verify the signature of the signed XML.
        RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider();
        rsaCsp.FromXmlString(PublicKeyXml);

        bool isValid = VerifyXml(xmlDoc, rsaCsp);

Вот код, который выполняет проверку подписи:

    // Verify the signature of an XML file against an asymmetric 
    // algorithm and return the result.
    public Boolean VerifyXml(XmlDocument Doc, RSA Key)
    {
        // Check arguments.
        if (Doc == null)
            throw new ArgumentException("Doc");
        if (Key == null)
            throw new ArgumentException("Key");

        // Create a new SignedXml object and pass it
        // the XML document class.
        System.Security.Cryptography.Xml.SignedXml signedXml = new SignedXml(Doc);

        // Find the "Signature" node and create a new XmlNodeList object.
        XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");

        // Throw an exception if no signature was found.
        if (nodeList.Count <= 0)
        {
            throw new CryptographicException("Verification failed: No Signature was found in the document.");
        }

        // Though it is possible to have multiple signatures on 
        // an XML document, this app only supports one signature for
        // the entire XML document.  Throw an exception 
        // if more than one signature was found.
        if (nodeList.Count >= 2)
        {
            throw new CryptographicException("Verification failed: More that one signature was found for the document.");
        }

        // Load the first <signature> node.  
        signedXml.LoadXml((XmlElement)nodeList[0]);

        // Check the signature and return the result.
        return signedXml.CheckSignature(Key);
    }

Чтобы проверить, что ваша подпись и проверка действительно работают, измените подпись или содержимое XML, которое было подписано. Вы должны увидеть, что проверка не удалась. В случае неудачной проверки ваше приложение может выдать или закрыть, или что-то еще.

2 голосов
/ 13 мая 2009

Вы можете попробовать защищенную конфигурацию в .NET, но это не очень просто. Вам необходимо зашифровать файл конфигурации на клиентском компьютере, поскольку защищенные поставщики конфигурации могут создавать зашифрованные данные для конкретного компьютера. Другими словами, если вы зашифруете раздел конфигурации на своем компьютере или компьютере сборки, вы не сможете расшифровать его на клиентских компьютерах. Вы также можете экспортировать и импортировать ключи шифрования на клиентский компьютер. Поэтому вам придется что-то делать во время установки, когда вы устанавливаете ключ на клиентском компьютере и используете этот ключ для шифрования раздела конфигурации. Взгляните на Реализация защищенной конфигурации с помощью приложений Windows . Как видите, это действительно не очень простое и чистое решение, которое усложняет развертывание.

С другой стороны, настройка WCF на стороне клиента программно проста. Вы можете настроить привязку и конечную точку в коде. Возможно, вы захотите сохранить адрес или URL-адрес в файле конфигурации, если вы все же хотите оставить некоторую гибкость при настройке, чтобы перенаправить клиентов на другой URL-адрес без новой сборки. Я думаю, что это лучший подход, поскольку я не думаю, что ваши привязки и конечные точки могут измениться после тестирования и развертывания приложения. Но вы лучше знаете свои требования :-) Я бы сказал, не переусердствуйте и не применяйте тяжелое и дорогое решение для чего-то, что на самом деле не может быть реальной проблемой.

2 голосов
/ 13 мая 2009

Полагаю, вариант 1 - это, вероятно, ваш лучший выбор. Тем не менее, мне интересно, стоит ли оно того (при условии, что у вас нет ничего особо чувствительного в конфигурационном файле, например, учетных данных или чего-то еще). Причина, по которой я привел это, заключается в том, что, если вы беспокоитесь о своих URL-адресах конечных точек и т. Д., Что ж, любой, обладающий очень простыми инструментами, может понять это за несколько секунд, используя анализатор сетевых протоколов.

...