Защита кода в книге Excel?
Я хочу создать книгу Excel, которая будет содержать проприетарные формулы и другую интеллектуальную собственность. Я скорее всего создаю эту книгу в Visual Studio 2010 с С#.
Насколько защищен код внутри этих проектов? Те же проблемы с рефлексией в С# по-прежнему применяются к этим проектам книг? Если да, существуют ли инструменты обфускации специально для этих типов книг?
Чтобы добавить к этому вопросу - как насчет хорошего 'ole VBA? Есть ли способ защитить этот код, если мы отправимся на маршрут VBA?
Ответы
Ответ 1
Как и другие ответы, безопасность VBA в Excel 2003 (.xls) ошибочна; пароль - это лишь немного раздражение, чаще всего не для самого разработчика. ИМХО, вам абсолютно лучше работать с VSTO, даже если безопасность VBA в Excel 2007+ (.xlsx) намного лучше, не говоря уже о VBA IDE, которая не видела улучшения в течение столетий (хотя не так верно с правой надстройкой VBE...).
Решение может заключаться в написании разумного кода в отдельной библиотеке, которую вызывает ваш проект VSTO; вместо сложных формул вы могли бы выставлять функции, которые выглядели бы как "черные ящики" (т.е. абстракция функциональности формулы); как это реализовано, просто не доступно никому без исходного кода), и без dll книга не может быть рассчитана (будет #NAME?
повсюду).
Например, вместо =some proprietary formula returning a Smurf
пользователи будут видеть =Smurf(SomeTableColumnName, SomeRangeName, SomeRangeReference, SomeCellReference)
. Конечно, это происходит за счет производительности, поэтому я бы сделал это только для вещей, которые действительно важны для защиты.
Я думаю, что пользователь, которому удается извлечь собственные формулы из такой библиотеки на стороне, заслуживает того, чтобы уйти с ними - между этим и Alt + F11 есть достаточно шаг; проприетарный код является "защищенным", как и любая другая сборка .net.
UPDATE
По-прежнему без использования каких-либо сторонних библиотек, если для проприетарного кода не требуется совместимость с Excel, возможно, лучшим решением может быть создание функции в VBA (т.е. оставить промежуточную часть Excel в Excel) и передать только примитивные типы ( VBA Integer
= > .net Int16
; VBA Long
= > .net Int32
, строки и т.д.) В библиотеку COM-видимости, которая даже не требует использования взаимодействия Excel; это будет COM-interop вместо Excel interop, и удар производительности будет значительно уменьшен, хотя все еще присутствует (он остается .net-управляемым кодом "разговаривает" с неуправляемым COM).
Ответственность за код VBA будет заключаться в том, чтобы читать и записывать в/из рабочих листов, а роль библиотеки видимых в COM-объектах - выполнять вычисления, которые должны выполняться из значений, передаваемых кодом VBA; конечно, код VBA был бы легко доступен пользователю (Alt + F11), но опять же они не могли получить доступ к фактической реализации расчета. И тогда код VBA может быть защищен паролем, а результаты расчета без DLL будут либо 0
, либо #VALUE!
, в зависимости от того, как реализован код VBA.
Ключ должен оставить спецификацию Excel в Excel и получить библиотеку .net, где это возможно, без ссылки на сборники Excel interop - например, функция VBA возьмет ссылку на ячейку, возьмет ее значение (возможно, проверит ее) и передать его в сборку .net, которая вернет другой примитивный тип, который VBA вернется в Excel.
Другим плюсом является то, что код библиотеки с проприетарными вычислениями можно было бы повторно использовать, если бы вы когда-либо "конвертировали" книгу Excel в, скажем, веб-приложение.
Ответ 2
Для справок в будущем: вот 2 новых инновационных продукта, которые помогут решить вашу конкретную проблему:
1) https://HiveLink.io: - Используя HiveLink, вы можете создать "облегченную" версию вашей электронной таблицы, которую вы даете своим пользователям но он не содержит никаких ваших чувствительных формул VBA или вычислений. Вы удаляете интеллектуальную собственность из легкой электронной таблицы и отправляете приглашения для своих пользователей, чтобы загрузить эту таблицу. Когда ваши пользователи вводят свои входные данные, HiveLink поставляет данные в свою электронную таблицу для обработки данных, а затем автоматически возвращает результаты пользователю.
Хорошая вещь об этом подходе заключается в том, что невозможно воспроизвести конструкцию с помощью .NET-отражения или даже кода сборки, потому что вы полностью удаляете код со своего компьютера. Это самый безопасный вариант, и отлично, если ваша модель подходит для дизайна входного/выходного roundtrip - не настолько велика, если вам требуется интерактивный код на стороне клиента, который происходит мгновенно. Если вам нужен быстрый интерактивный код на стороне клиента, обычно это менее чувствительно, и вы можете использовать защиту рабочей книги или даже скомпилировать базовый код, используя что-то вроде DoneEx Excel Compiler и иметь защиту, используя комбинацию Excel Compiler и HiveLink.
2) http://FCell.io: Это позволяет вам создавать .NET-код непосредственно в электронной таблице. Он даже поставляется с окном редактора кода в электронной таблице, вроде замены существующего редактора кода VBA на редактор кода .NET. Объектная модель в редакторе кода немного менее полная, чем обычная, но вы также можете создавать панели задач и вставлять их в книгу для распространения, чтобы ваши пользователи даже не нуждались в установке! Я не уверен, насколько безопасен ваш код, встроенный в рабочую книгу, но я на 100% уверен, что люди могут добраться до вашего кода, если это будет достаточно для них.
Дополнительные комментарии Re Mat Mug полезный ответ:
Re: Производительность - на самом деле вы можете заметить значительный прирост производительности благодаря внедрению в .NET, особенно если вы используете многопоточность, что Excel не делает вообще с UDF или макросами. Я видел увеличение 100x повторного написания кода некоторых моих клиентов в библиотеках .NET(для вычислений большой обработки). Вам также может быть намного проще поддерживать и улучшать код .NET, чем VBA. Я много сделал для преобразования кода VBA и функциональности в .NET-код и никогда не замечал проблемы с производительностью при правильном выполнении.
Re: Пользователи, желающие получить доступ, отражая библиотеки .NET? - Я совершенно не согласен с этим. Очень легко получить доступ к .NET-коду с помощью отражения, возможно, даже проще, чем взломать слабые пароли Excel. Если у вас действительно есть чувствительные вычисления, которые вы хотите защитить, то лучше всего использовать что-то вроде HiveLink, чтобы полностью удалить возможность обратной инженерии, или использовать обфускацию, чтобы сделать ее более сложной/крайне раздражающей. Для обфускации я использую CryptoObfuscator ($) и Dotfuscator ($$$). Я бы не стал делиться конфиденциальной моделью VBA для моих клиентов в библиотеках .NET для excel без этого. Я также иногда использую CryptoLicensing, чтобы позволить им контролировать, кто может получить доступ к их функциональности DLL, создавая лицензии для каждого пользователя.
Re: Оставив код VBA, ответственный за запись/чтение в/из рабочего листа, я тоже против этого. Я бы порекомендовал оставить как можно меньше кода в VBA и сделать высокий уровень вызова .NET, оставив чтение/запись в .NET-плагине. Используйте имя, указанное на вашем листе, чтобы определить ваши входы/выходы и местоположения данных, а затем определите эти именованные диапазоны как константы в вашей библиотеке .NET. В вашей библиотеке вы можете легко читать диапазоны и писать в диапазоны. Это намного чище и легче поддерживать этот путь.
При создании любой библиотеки расширений для Excel, где вы хотите вызывать внешние функции из VBA, вы должны сделать свою библиотеку COM видимой. Есть несколько способов сделать это: я настоятельно рекомендую не регистрировать вашу библиотеку с помощью списка COM файлов Windows с помощью regsvr32 - избегайте его любой ценой!
Лучший способ зарегистрировать свою библиотеку - загрузить ее с помощью ExcelDna, который позволяет динамически загружать вашу DLL при каждом запуске Excel без необходимости постоянно определять каждый класс с помощью COM-интерфейса в реестре (кошмар при обновлении версий). Вы создаете XLL файл, который может иметь DLL, упакованную внутри - и вы можете сказать, что Excel загружает XLL каждый раз, когда он запускается, помещая ключ в реестр. Преимущество в том, что это не требует, чтобы вы сохраняли весь COM-интерфейс в реестре, поэтому очень легко управлять новыми версиями.
Следовательно, ваш код VBA может выглядеть примерно так:
Sub Button_Click()
Call ThisWorkbook.EnsureLibraryInitialized
Call ThisWorkbook.MyLibrary.ReadRangesAndWriteResults(someInputParam)
End Sub
Обратите внимание, что VBA будет искать этот метод ReadRangesAndWriteResults во время выполнения. Если вы выставляете метод для времени компиляции в VBA, вам придется зарегистрировать его подпись в интерфейсе COM в реестре - стоит избегать любой ценой!!!
Модуль этой книги:
Public MyLibrary as Object
public sub Workbook_Open()
EnsureLibraryInitialized
End Sub
public Sub EnsureLibraryInitialized()
Dim addin As COMAddIn
If MyLibrary is Nothing Then
For Each addin In Application.COMAddIns
If InStr(addin.Description, "MyLibrary.COMHelper") Then
If addin.object Is Nothing Then
'complain it can't connect to library, tell user to reinstall it
Else
Set MyLibrary = addin.object
Exit For
End If
Next
End if
End Sub
Re: Excel Interop и .NET-библиотеки - Хорошие точки Mat Mug, это может быть кошмар при использовании обычного Microsoft.Office.Interop.Excel. Поскольку вы получаете доступ к собственному коду из управляемой среды .NET, вы должны убедиться, что ваши объекты обертки .NET COM будут очищены должным образом, или вы получите зависание/процессы зомби Excel даже после закрытия Excel, и похоже, что оно исчезло/(посмотрите в диспетчере задач, они все еще могут быть там!)
Лучший способ найти это - использовать NetOffice, который в основном является клоном модели взаимодействия с Excel но создан для безопасного управления всеми этими проблемами для вас. Лучше также знать о хорошем безопасном обращении с COM-объектами, например здесь и здесь.
Удачи!
Ответ 3
Если вы сохраните книгу с паролем для открытия в виде XLSB (обратите внимание, что это НЕ защищает структуру рабочей книги и т.д.), книга зашифровывается с разумно защищенным шифрованием (сильнее в Excel 2013).
Но пользователь должен предоставить пароль, чтобы открыть его, что не подходит для некоторых сценариев использования.
Все остальные формы защиты Excel относительно слабы.
Защитный код в Excel лучше всего использовать с помощью С++ XLL.
Next best - это VB6 DLL (но теперь это мертвая технология и не будет работать в 64-разрядном Excel). Следующее лучшее - запутанное .NET, но вам действительно нужно использовать вид .NET. XLL-интерфейс, предоставляемый Addin Express или XL DNA, чтобы избежать низких характеристик производительности .NET Interop и VSTO.