Эффективный метод для шифрования файла лицензии? - PullRequest
21 голосов
/ 11 декабря 2008

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

Каковы некоторые методы шифрования файлов в C #, которые являются достаточно защищенными от взлома?

Ответы [ 9 ]

38 голосов
/ 11 декабря 2008

Звучит так, как будто вы хотите использовать публичную / частную криптографию для подписи токена лицензии (например, фрагмент 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;
    }

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

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

Обновление

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

7 голосов
/ 11 декабря 2008

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

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

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

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

6 голосов
/ 29 октября 2009

Ответ 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;
}
1 голос
/ 23 августа 2009

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

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

RSACryptoServiceProvider rsaKey = EncryptionUtils.GetRSAFromSnkFile(keyFilePath);

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

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

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

1 голос
/ 11 декабря 2008

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

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

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

1 голос
/ 11 декабря 2008

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

0 голосов
/ 07 ноября 2009

При реализации кода подписи / проверки будьте осторожны, чтобы не поместить его в отдельную сборку. Защита от несанкционированного доступа в Code Access Security теперь очень легко обойти, как описано в статье Защита от несанкционированного доступа в CAS нарушена: последствия для лицензирования программного обеспечения .

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

0 голосов
/ 21 августа 2009

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

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

0 голосов
/ 11 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...