【发布时间】:2015-03-13 15:11:14
【问题描述】:
我在 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 抛出“Bad Data”异常。
我试过了
- 不同的 .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
...
【问题讨论】:
-
我对 .NET 和 mono 进行的一些快速健全性检查没有发现任何问题。我确实注意到无效的
Seed属性可能会导致“错误数据”错误,但我也希望单声道也会出现这种情况。更多信息可能会有所帮助:(1)您如何生成私钥(例如,在 .NET 或单声道的DSACryptoServiceProvider中的一个或另一个中)? (2) 您能否提供更多代码(例如,用于加载DSAParameters的代码,也许问题就在那里)。 (3) 你说.NET签名总是无效的,你是怎么验证的? -
@softwariness 我用更多信息更新了我的问题。所以,特别是; 1) 密钥不是在 .NET 中生成,而是在 Java 中生成 2) 加载代码完全相同,当我对生成的原始私钥字节进行逐字节比较时,它们在我之前完全相同使用 ImportParameters 加载它们
-
Java 和 mono 代码运行在什么操作系统和架构上?我想知道问题是否是错误的字节顺序。
-
Java 代码在 Linux 和 Windows 上运行(均经过测试) - .NET 代码(Mono 和 MS)都在 PC(和 Mac,对于 Mono 部分)上运行,因此,鉴于 Mono->Java无论平台如何,路径都可以工作,这似乎不是字节顺序问题。特别是因为原始字节在加载之前是相同的。我开始怀疑 MS .NET 是否有某种规则,可以让您将哪些整数用于 DSA,这些整数隐藏在某个地方……这有意义吗?
-
我实际上是在考虑
DSACryptoServiceProvider的 Mono vs .NET 实现中的字节序,而不是从文件中加载参数(即进入ImportParameters的字节是相同的,但该方法的解释不同),但可能并非如此。 Re .NET 限制值,这是可能的,或者它可能是一个错误。您能否提供一些无法导入 .NET 的示例参数的 hex 或 base64,以便我可以尝试重现它?
标签: c# unity3d mono cryptography dsa