Подтвердить что ты не робот

Лицензия для настольного приложения С#

Как я могу добавить лицензию на свое настольное приложение С#? Мне нужно найти подходящий бесплатный метод предотвращения несанкционированных пользователей, устанавливающих мое программное обеспечение.

4b9b3361

Ответ 2

Возможно, я немного опоздал, но я потратил немного времени на разработку быстрого и эффективного метода защиты небольшого приложения С#, и я хотел бы поделиться своими результатами.

Кажется, вы можете легко создать свою, довольно безопасную систему лицензирования, используя RSA.

Очевидно, что нет ничего пуленепробиваемого, когда дело доходит до защиты программного обеспечения (это, как защита вашего дома от грабителей: тревоги, лай собаки и заборы делают это больше проблем, чем это стоит, но они не остановят кого-то, кто решил попасть )

Таким образом, делая больше проблем, чем стоит, это ключевая фраза в защите программного обеспечения: если вы предлагаете $1,000,000 E.R.P. системы, вы бы хотели иметь действительно хорошую защиту, разрешенную с помощью веб-сервиса (и пользователи, платящие столько за систему, не будут иметь проблемы с возможностью постоянного доступа в систему)

Однако, если вы загружаете только $5- $30 за небольшое приложение, пользователи не будут мириться с очень тяжелой авторизацией.

Я думаю, что самой простой системой для создания является цифровая подпись файла лицензии, который содержит детали продукта, пользователя и его продолжительность.

Это означает, что любая модификация файла лицензии делает цифровую подпись недопустимой.

Цифровая подпись может быть получена из класса DSACryptoServiceProvider с использованием метода SignData.

Для подписи данных требуется закрытый ключ, а общедоступная часть этого ключа может использоваться для проверки подписи: (таким образом, открытый ключ должен быть доступен приложением)

У DSAXCryptoServiceProvider есть методы для создания и использования ключей:

DSACryptoServiceProvider.ToXMLString(bool includePrivate);

возвращает общедоступные или общедоступные и приватные ключи в настоящее время в поставщике услуг в виде XML-строки.

DSACryptoServiceProvider.FromXMLString(String xmlString)

Этот метод устанавливает новый DSACryptoServiceProvider с существующими частными или открытыми ключами, полученными из DSACryptoServiceProvider.ToXMLString()

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

Это можно получить, добавив дополнительный ресурс для приложения (например .dll, который содержит основную логику для приложения или даже самого .exe) - таким образом, если открытый ключ изменен, этот дополнительный (скрытый ) подпись станет недействительной.

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

У меня есть примерная система, которую я написал, но она слишком велика, чтобы процитировать полностью, но это метод CreateLicense из нее:

    /// <summary>
    /// use a private key to generate a secure license file. the private key must match the public key accessible to
    /// the system validating the license.
    /// </summary>
    /// <param name="start">applicable start date for the license file.</param>
    /// <param name="end">applicable end date for the license file</param>
    /// <param name="productName">applicable product name</param>
    /// <param name="userName">user-name</param>
    /// <param name="privateKey">the private key (in XML form)</param>
    /// <returns>secure, public license, validated with the public part of the key</returns>
    public static License CreateLicense(DateTime start, DateTime end, String productName, String userName, String privateKey)
    {
        // create the licence terms:
        LicenseTerms terms = new LicenseTerms()
        {
            StartDate = start,
            EndDate = end,
            ProductName = productName,
            UserName = userName
        };

        // create the crypto-service provider:
        DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

        // setup the dsa from the private key:
        dsa.FromXmlString(privateKey);

        // get the byte-array of the licence terms:
        byte[] license = terms.GetLicenseData();

        // get the signature:
        byte[] signature = dsa.SignData(license);

        // now create the license object:
        return new License()
        {
            LicenseTerms = Convert.ToBase64String(license),
            Signature = Convert.ToBase64String(signature)
        };
    }

Метод проверки:

    /// <summary>
    /// validate license file and return the license terms.
    /// </summary>
    /// <param name="license"></param>
    /// <param name="publicKey"></param>
    /// <returns></returns>
    internal static LicenseTerms GetValidTerms(License license, String publicKey)
    {
        // create the crypto-service provider:
        DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

        // setup the provider from the public key:
        dsa.FromXmlString(publicKey);

        // get the license terms data:
        byte[] terms = Convert.FromBase64String(license.LicenseTerms);

        // get the signature data:
        byte[] signature = Convert.FromBase64String(license.Signature);

        // verify that the license-terms match the signature data
        if (dsa.VerifyData(terms, signature))
            return LicenseTerms.FromString(license.LicenseTerms);
        else
            throw new SecurityException("Signature Not Verified!");
    }

Класс лицензионных условий:

    /// <summary>
    /// terms of the license agreement: it not encrypted (but is obscured)
    /// </summary>
    [Serializable]
    internal class LicenseTerms
    {
        /// <summary>
        /// start date of the license agreement.
        /// </summary>
        public DateTime StartDate { get; set; }

        /// <summary>
        /// registered user name for the license agreement.
        /// </summary>
        public String UserName { get; set; }

        /// <summary>
        /// the assembly name of the product that is licensed.
        /// </summary>
        public String ProductName { get; set; }

        /// <summary>
        /// the last date on which the software can be used on this license.
        /// </summary>
        public DateTime EndDate { get; set; }

        /// <summary>
        /// returns the license terms as an obscure (not human readable) string.
        /// </summary>
        /// <returns></returns>
        public String GetLicenseString()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // create a binary formatter:
                BinaryFormatter bnfmt = new BinaryFormatter();

                // serialize the data to the memory-steam;
                bnfmt.Serialize(ms, this);

                // return a base64 string representation of the binary data:
                return Convert.ToBase64String(ms.GetBuffer());

            }
        }

        /// <summary>
        /// returns a binary representation of the license terms.
        /// </summary>
        /// <returns></returns>
        public byte[] GetLicenseData()
        {
            using (MemoryStream ms = new MemoryStream())
            {
                // create a binary formatter:
                BinaryFormatter bnfmt = new BinaryFormatter();

                // serialize the data to the memory-steam;
                bnfmt.Serialize(ms, this);

                // return a base64 string representation of the binary data:
                return ms.GetBuffer();

            }
        }

        /// <summary>
        /// create a new license-terms object from a string-representation of the binary
        /// serialization of the licence-terms.
        /// </summary>
        /// <param name="licenseTerms"></param>
        /// <returns></returns>
        internal static LicenseTerms FromString(String licenseTerms)
        {

            using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(licenseTerms)))
            {
                // create a binary formatter:
                BinaryFormatter bnfmt = new BinaryFormatter();

                // serialize the data to the memory-steam;
                object value = bnfmt.Deserialize(ms);

                if (value is LicenseTerms)
                    return (LicenseTerms)value;
                else
                    throw new ApplicationException("Invalid Type!");

            }
        }

    }

Ответ 3

Мы используем Eziriz.NET Reactor для обфускации и лицензирования нашего коммерческого программного обеспечения. Это довольно хорошо, и это не так дорого.

(У меня нет связи с эзиризом, я всего лишь насыщенный клиент)

Изменить: извините, слишком поздно увидел слово "свободный"

Ответ 5

Будьте осторожны с тем, как много усилий вы прилагаете для защиты своего приложения; это может быть потрачено впустую, если его легко сломать или выключить для пользователей, если они очень сильны (например, при вводе пароля каждый раз при запуске).

Интересную статью о защите программного обеспечения (игр) можно найти здесь: http://www.positech.co.uk/talkingtopirates.html

Ответ 6

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

У меня лучший опыт работы с библиотекой Treek Licensing. Это дешево даже для одного разработчика, безопасно и с хорошей поддержкой. При сравнении затрат TLL дешевле, чем аренда собственного разработчика для выполнения той же работы.

Также вам нужно будет защитить свои источники. Для этого мы используем EAZ Fuscator, но есть и бесплатные варианты.