5 ответов:
Существует множество систем управления лицензиями для .NET (есть даже однавстроенная для управления лицензиями ). Быстрый поиск в Google для ".NET license manager" вызвал системуOpen License , которая является бесплатной.
Я думаю, что вы можете легко найти больше.
Возможно, я немного опоздал, но я потратил немного времени, пытаясь разработать быстрый и эффективный метод защиты небольшого приложения C#, и я хотел бы поделиться своими результатами.
Похоже, что вы можете построить свою собственную, достаточно безопасную систему лицензирования, используя RSA достаточно легко.
Очевидно, что ничто не является пуленепробиваемым, когда речь заходит о защите программного обеспечения (это похоже на защиту вашего дома от взломщиков: сигнализация, лающие собаки и заборы создают больше проблем, чем это стоит, но они не остановит кого-то, кто решил войти)Таким образом, делая его более сложным, чем это стоит, ключевая фраза в защите программного обеспечения: если вы предлагаете систему за $ 1,000,000 E. R. P., вы хотели бы иметь действительно хорошую защиту, которая авторизована через веб-сервис (и пользователи, которые платят столько за систему, не будут иметь проблем с предоставлением этой системе постоянного доступа в интернет){[4]]}
Однако, если вы берете только $ 5 - $ 30 за небольшое приложение, пользователи не собираются мириться с очень тяжелым вручил разрешение.
Я думаю, что самая простая система для производства-это цифровая подпись файла лицензии, который содержит сведения о продукте, пользователе и его продолжительности.Это означает, что любое изменение файла лицензии делает цифровую подпись недействительной.
Цифровую подпись можно получить из класса DSACryptoServiceProvider, используя метод SignData.
Для подписи данных требуется закрытый ключ, а открытая часть этого ключа может использоваться для проверки подпись: (таким образом, открытый ключ должен быть доступен приложению)
DSAXCryptoServiceProvider имеет методы для создания и использования ключей:
DSACryptoServiceProvider.ToXMLString(bool includePrivate);
Возвращает открытый или открытый и закрытый ключи, находящиеся в данный момент в поставщике услуг, в виде строки XML.
DSACryptoServiceProvider.FromXMLString (строка xmlString)
Этот метод устанавливает новый DSACryptoServiceProvider с существующими private или public ключи, полученные от DSACryptoServiceProvider.ToXMLString ()
Единственным недостатком в безопасности этой системы была бы возможность взлома пользователем своего собственного открытого ключа. Это позволит им создавать свои собственные файлы лицензий из собственного закрытого ключа.Это можно обойти, дополнительно подписав необходимый ресурс для приложения (например, a .dll, которая содержит необходимую логику для приложения, или даже .exe сам) - таким образом, если открытый ключ изменена, эта дополнительная (скрытая) подпись станет недействительной.
Другие способы улучшить это включают скрытие условий лицензии (сериализация структуры данных, содержащей условия лицензии, с помощью двоичного форматера в массив байтов, а затем с помощью преобразования.ToBase64String () будет довольно эффективно скрывать условия лицензирования, и даже если пользователь смог бы заменить открытый ключ, им все равно нужно было бы разработать представление данных)
У меня есть пример системы I написал, но он слишком велик, чтобы цитировать полностью, но это метод 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's 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!"); } } }
Мы используем Eziriz .Чистый реактор для обфускации и лицензионного коммерческого софта. Это довольно хорошо, и это не так дорого.(у меня нет никакой связи с эзириз, я просто удовлетворенный клиент)
Edit: извините, слишком поздно увидел слово "бесплатно"
Будьте осторожны с тем, сколько усилий вы вкладываете в защиту вашего приложения; это может быть потрачено впустую, если оно легко сломано или не подходит для пользователей, если очень сильно (например, необходимость вводить пароль каждый раз, когда оно запускается).
Интересную статью о защите программного обеспечения (игр) можно найти здесь: http://www.positech.co.uk/talkingtopirates.html
Comments