2015-03-13 5 views
3

У меня есть идентичный код компилируется и работает под Mono (Unity 4.5) и MS .NET:Разница между реализацией криптографии .NET 3.5 и реализацией Mono 2.x?

DSAParameters privateKey; 
... 
DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(csp); 
dsa.PersistKeyInCsp = false; 
dsa.ImportParameters(privateKey); 

Закрытый ключ загружается с диска и байты загружены, и целые быть установлен в «PrivateKey "идентичны в версиях Mono и MS .NET.

В версии .NET dsa.ImportParameters выбрасывается исключение «Bad Data».

Я попытался

  • различных .NET параметров (3,5 минимально, AnyCPU/x86/x64)
  • разных ключей (некоторый бросок, некоторые нет, но подписи .NET всегда (?) недействительным, когда я проверить их, в то время как те, сгенерированные с же ключами и того же сообщения в Mono работает нормально.)

есть некоторая фундаментальная основная разница между тем, как MS DSA и одно из работы Моно, под капотом, что может вызвать это ...?

Любой свет сарай приветствовать ... это немного головы скребок ...

Некоторые подробнее:

  • Ключ генерируется в Java и экспортируется после преобразование из формата DER для работы с .NET (P1363; просто большие целые числа один за другим)
  • Ключ загружается с диска с использованием BinaryReader и целочисленных значений, загружаемых как byte [] в DSAParameters (P, Q , G и X)
  • Открытый ключ загружается в Java-приложение, которое использует реализацию Oracle для проверки подписи
  • Весь код C# является «симметричным», т. Е. Используется как есть в приложениях Mono и MS .NET.

Update 2

Хорошо, я не схожу с ума; этим утром я снова попытался; одно приложение .NET работает на Mac (с использованием Mono Develop, простой ваниль) и один на Windows (Visual Studio 2010). Одинаковые байты с секретным ключом, один и тот же путь кода (по крайней мере, до C#) - то же исключение «плохих данных» в Windows. Вот ключ:

P: 17801190547854226652823756245015999014523215636912067427327445031444286578873 
70207706126952521234630795671567847784664499706507709207278570500096683881440341 
29745221171818506047231150039301079959358067395348717066319802262019714966524135 
060945913707594956514672855690606794135837542707371727429551343320695239 

Q: 864205495604807476120572616017955259175325408501 

G: 17406820753240209518581198
58231478515974089409507253077970949157594923683005742524387610370844734671801488 
76118103083043754985190983472601550494691329488083395492313850000361646482644608 
492304078721818959999056496097769368017749273708962006689187956744210730 

X: 3505625379966178555918512548923624458026758122 

...

+0

Некоторые быстрые проверки здравомыслия, которые я делал с .NET и моно, не обнаружили проблем. Я отмечаю, что недопустимое свойство 'Seed' может привести к ошибке« Bad Data », но я ожидаю, что с mono тоже. Дополнительная информация может помочь: (1) Как вы создаете закрытый ключ (например, в том или ином режиме «DSACryptoServiceProvider» .NET или моно)? (2) Можете ли вы предоставить еще какой-то код (например, для загрузки «DSAParameters», возможно, проблема есть). (3) Вы говорите, что подписи .NET всегда недействительны, как вы их проверяете? – softwariness

+0

@softwariness Я обновил свой вопрос с дополнительной информацией. Так, в частности; 1) ключ не генерируется в .NET, а в Java 2) код загрузки точно такой же, и когда я делал байтовое сравнение полученных в результате необработанных байтов с закрытым ключом, они «точно» одинаковы до того, как я загружу их с помощью ImportParameters – SonarJetLens

+0

Какая ОС и архитектура - это Java и моно-код? Интересно, не проблема в том, что проблема неверна. – softwariness

ответ

0

короткий ответ, что хэш-коды могут отличаться в разных версиях Framework .NET и платформ, таких как 32-битных и 64-битных платформ; или между Microsoft и Mono.

Это можно прочитать здесь: Object.GetHashCode, прочитать примечания.

Я уже сталкивался с этой ситуацией при разработке кросс-платформенных многопользовательских игр в Unity3D. Поэтому вам нужно будет использовать собственную хэш-функцию или использовать симметричный алгоритм для шифрования ваших данных.

Из документации я прочитал, что DSACryptoServiceProvider является асимметричным по своей природе и использует хеши для создания цифровых подписей. Вот ссылка: DSACryptoServiceProvider Class, прочитайте примечания.

+0

Но используемым алгоритмом хэширования будет SHA1, который не зависит от хеш-кодов объекта (которые в любом случае не используются, поскольку это хэш последовательности байтов, а не объекта) ... правильно? – SonarJetLens

1

.NET Framework ожидает, что некоторые отношения размера необходимо поддерживать:

  • В: 20 байт
  • G: такой же длины, как P
  • Y, если таковой присутствует: такой же длины, как P
  • семян , если они присутствуют: 20 байт
  • X, если присутствуют: 20 байт

se являются только сквозными требованиями основного поставщика криптографии: https://msdn.microsoft.com/en-us/library/windows/desktop/aa381987(v=vs.85).aspx#PRIVK_BLOB.

Основываясь на длине ваших значений выше, вам, вероятно, потребуется левая панель X с нулями.

+0

Прошло некоторое время с тех пор, как эта проблема и проект были перенесены в совершенно другом направлении, но ваше предложение кажется разумным. Если мне удастся снова выкопать проект, я попробую это подтвердить. – SonarJetLens