3

我在 Mono (Unity 4.5) 和 MS .NET 下编译和运行相同的代码:

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

私钥是从磁盘加载的,在 Mono 和 MS .NET 版本中,“privateKey”中加载的字节和设置的整数是相同的。

在 .NET 版本中,dsa.ImportParameters 会引发“错误数据”异常。

我努力了

  • 不同的 .NET 设置(最低 3.5,AnyCPU/x86/x64)
  • 不同的键(有些会抛出,有些不会,但是当我验证它们时,.NET 签名总是(?)无效,而在 Mono 中使用相同的键和相同的消息生成的那些可以正常工作。)

MS DSA 的实现方式和 Mono 的实现方式之间是否存在一些根本的潜在差异,这可能会导致这种情况..?

任何灯棚都是最受欢迎的……这有点让人头疼……

更多信息:

  • 密钥在 Java 中生成并在从 DER 格式转换为与 .NET 一起使用后导出(P1363;只是一个接一个的大整数)
  • 使用 BinaryReader 从磁盘加载密钥,并将整数值作为 byte[] 加载到 DSAParameters(P、Q、G 和 X)中
  • 公钥加载到 Java 应用程序中,该应用程序使用 Oracle 实现来验证签名
  • 所有 C# 代码都是“对称的”,即在 Mono 和 MS .NET 应用程序中都按原样使用。

更新 2

好吧,我不会发疯的;今天早上我又试了一次;相同的 .NET 应用程序在 Mac 上运行(使用 Mono Develop,普通香草)和一个在 Windows 上(Visual Studio 2010)。加载相同的私钥字节,相同的代码路径(至少就 C# 而言) - 仅在 Windows 上出现相同的“坏数据”异常。这是关键:

P: 17801190547854226652823756245015999014523215636912067427327445031444286578873
70207706126952521234630795671567847784664499706507709207278570500096683881440341
29745221171818506047231150039301079959358067395348717066319802262019714966524135
060945913707594956514672855690606794135837542707371727429551343320695239

Q: 864205495604807476120572616017955259175325408501

G: 17406820753240209518581198012352343653860449079456135097849583104059995348845
58231478515974089409507253077970949157594923683005742524387610370844734671801488
76118103083043754985190983472601550494691329488083395492313850000361646482644608
492304078721818959999056496097769368017749273708962006689187956744210730

X: 3505625379966178555918512548923624458026758122

...

4

2 回答 2

1

.NET Framework 期望保持一些大小关系:

  • 问:20 字节
  • G:与P相同的长度
  • Y,如果存在:与 P 相同的长度
  • 种子(如果存在):20 字节
  • X,如果存在:20 字节

这些只是底层加密提供程序的传递要求:https ://msdn.microsoft.com/en-us/library/windows/desktop/aa381987(v=vs.85).aspx#PRIVK_BLOB 。

根据上述值的长度,您可能需要用零填充 X。

于 2016-08-01T22:39:18.897 回答
0

简短的回答是 .NET Framework 版本和平台之间的哈希码可能不同,例如 32 位和 64 位平台;或者在微软和 Mono 之间。

这可以在这里阅读: Object.GetHashCode,阅读备注。

之前在Unity3D中开发跨平台多人游戏的时候,就遇到过这种情况。因此,您将需要使用自己的哈希函数,或使用对称算法来加密您的数据。

从文档中我读到 DSACryptoServiceProvider 本质上是不对称的,并使用哈希来创建数字签名。这是链接: DSACryptoServiceProvider 类,阅读备注。

于 2015-03-28T22:33:01.967 回答