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

Эффективный метод шифрования файла лицензии?

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

Каковы некоторые методы шифрования файлов на С#, которые достаточно защищены от несанкционированного доступа?

4b9b3361

Ответ 1

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

1) Создайте ключевую пару для вашей компании. Это можно сделать в командной строке Visual Studio с помощью инструмента SN. Синтаксис:

sn -k c:\keypair.snk

2) Используйте ключевую пару для строгого имени (т.е. знака) вашего клиентского приложения. Вы можете установить это, используя вкладку подписи на странице свойств вашего приложения.

3) Создайте лицензию для своего клиента, это должен быть документ XML и подписать его с помощью вашего закрытого ключа. Это включает простое вычисление цифровой подписи, и шаги для ее выполнения можно найти по адресу:

http://msdn.microsoft.com/en-us/library/ms229745.aspx

4) На клиенте при проверке лицензии вы загружаете XmlDocument и используете свой открытый ключ, чтобы проверить подпись, чтобы доказать, что лицензия не подделана. Подробности о том, как это сделать, можно найти по адресу:

http://msdn.microsoft.com/en-us/library/ms229950.aspx

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

Чтобы вытащить открытый ключ из сборки клиента, вы хотите использовать код, похожий на:

    /// <summary>
    /// Retrieves an RSA public key from a signed assembly
    /// </summary>
    /// <param name="assembly">Signed assembly to retrieve the key from</param>
    /// <returns>RSA Crypto Service Provider initialised with the key from the assembly</returns>
    public static RSACryptoServiceProvider GetPublicKeyFromAssembly(Assembly assembly)
    {
        if (assembly == null)
            throw new ArgumentNullException("assembly", "Assembly may not be null");

        byte[] pubkey = assembly.GetName().GetPublicKey();
        if (pubkey.Length == 0)
            throw new ArgumentException("No public key in assembly.");

        RSAParameters rsaParams = EncryptionUtils.GetRSAParameters(pubkey);
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.ImportParameters(rsaParams);

        return rsa;
    }

Я загрузил образец класса с множеством полезных Encryption Utilities на Snipt по адресу: http://snipt.net/Wolfwyrd/encryption-utilities/, чтобы помочь вам в пути,

Я также включил образец программы по адресу: https://snipt.net/Wolfwyrd/sign-and-verify-example/. Образец требует, чтобы вы добавили его в решение с библиотекой утилиты шифрования и предоставили тестовый XML файл и файл SNK для подписания. Проект должен быть настроен для подписания с созданным SNK. Он демонстрирует, как подписать тестовый XML файл с помощью закрытого ключа из SNK, а затем проверить из открытого ключа в сборке.

Обновление

Добавлен текущее сообщение в блоге с приятным подробным просмотром файлов лицензий

Ответ 2

Использовать подписанный XML файл. Подпишите его с помощью ключевой части ключевой пары и проверьте ее с помощью открытого ключа в вашем программном обеспечении. Это дает вам возможность проверить, была ли изменена лицензия, а также проверить, действительно ли файл лицензии действителен.

Подписание и проверка подписанного XML файла документируется в MSDN.

Конечно, логично, что вы подписываете файл лицензии в своей собственной компании и отправляете файл лицензии клиенту, который затем помещает файл лицензии в папку для чтения.

Конечно, люди могут вырезать/взломать вашу распределенную сборку и вырвать проверку знака xml, но опять же, они всегда смогут это сделать, независимо от того, что вы делаете.

Ответ 3

Ответ Wolfwyrd превосходный, но я просто хотел предложить muich более простой вариант метода Wolfwyrd GetPublicKeyFromAssembly (который использует множество вспомогательных методов из библиотеки Wolfwyrd, любезно предоставленной).

В этой версии это все, что вам нужно:

/// <summary>
/// Extracts an RSA public key from a signed assembly
/// </summary>
/// <param name="assembly">Signed assembly to extract the key from</param>
/// <returns>RSA Crypto Service Provider initialised with the public key from the assembly</returns>
private RSACryptoServiceProvider GetPublicKeyFromAssembly(Assembly assembly)
{
    // Extract public key - note that public key stored in assembly has an extra 3 headers
    // (12 bytes) at the front that are not part of a CAPI public key blob, so they must be removed
    byte[] rawPublicKeyData = assembly.GetName().GetPublicKey();

    int extraHeadersLen = 12;
    int bytesToRead = rawPublicKeyData.Length - extraHeadersLen;
    byte[] publicKeyData = new byte[bytesToRead];
    Buffer.BlockCopy(rawPublicKeyData, extraHeadersLen, publicKeyData, 0, bytesToRead);

    RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();
    publicKey.ImportCspBlob(publicKeyData);

    return publicKey;
}

Ответ 4

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

Ответ 5

Единственный способ обеспечить какую-то безопасность при лицензировании - заставить интернет-логин использовать учетные данные самостоятельно (действительно абстрактно говоря).

Все другие методы требуют больше времени и, следовательно, больше денег, чтобы реализовать, как взломать и оскорбить ваше программное обеспечение, а не покупать лицензию.

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

Ответ 6

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

Для подписания файла я использовал это:

RSACryptoServiceProvider rsaKey = EncryptionUtils.GetRSAFromSnkFile(keyFilePath);

Для проверки файла я использовал это:

RSACryptoServiceProvider rsaKey = EncryptionUtils.GetPublicKeyFromAssembly
   (System.Reflection.Assembly.GetExecutingAssembly());

BTW: Я заметил, что проверка подписи XML игнорирует комментарии XML.

Ответ 7

или, возможно, вы хотите привязать лицензию к определенному компьютеру, например, создав лицензионный ключ на основе значения md5 привода c компьютера. то ваша лицензия будет специфичной для машины.

Ответ 8

Когда вы реализуете свой код подписи/проверки, будьте осторожны, чтобы не поместить его в отдельную сборку. Защита доступа к кодам безопасности теперь очень легко обойти, как объясняется в статье CAS Tamper-Proofing Broken: последствия для лицензирования программного обеспечения.

Обязательный отказ от ответственности и плагин: компания, которую я основал, производит лицензионное решение OffByZero Cobalt.

Ответ 9

RE: Не включайте весь код в свой код. Используйте sn -p для извлечения публичной части в файл. Используйте это в своем коде, который вы распространяете для проверки лицензии.

Используя код из статей MSDN, я создал небольшое приложение (LicMaker), чтобы облегчить это. Приложение подписано с полной парой ключей. Вход представляет собой файл без знака .XML. Вывод - это оригинальная подпись XML + в подписанном файле .LIC. Мой продукт также подписан одним и тем же полным файлом пары ключей. Продукт проверяет, что файл .LIC не был изменен. Прекрасно работает. Я не использовал sn -p для этого решения.