2015-03-13 55 views
3

我有相同的代码被编译和Mono(统一4.5)和MS .NET下运行:.NET 3.5加密实现和Mono 2.x实现之间的区别?

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

私钥从磁盘加载和被加载的字节数,以及整数设定,在“专用密钥“在Mono和MS .NET版本中是相同的。

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

我已经试过

  • 不同.NET设置(3.5最少,AnyCPU/86/64)
  • 不同的密钥 (一些罚球,有的没有,但.NET签名总是(? )当我对其进行验证,而用 相同的密钥和单声道相同的消息所产生的那些做工精细 无效。)

有没有顺便MS DSA之间的一些基本的底层差异实施和从单声道工作,在引擎盖下,这可能会导致这.. ..?

任何光棚是最欢迎的...这是一个有点头饼刷的......

一些更多的信息:

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

更新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和mono做的一些快速完整性检查没有发现任何问题。我注意到一个无效的“种子”属性可能会导致“错误的数据”错误,但我也期望与单声道。一些更多的信息可能会有所帮助:(1)您如何生成私钥(例如,在.NET或单声道的DSACryptoServiceProvider中)? (2)你能否提供更多的代码(例如加载'DSAParameters',也许问题出在那里)。 (3)你说.NET签名总是无效的,你如何验证它们? – softwariness 2015-03-13 18:45:51

+0

@softwar我更新了一些更多的信息我的问题。所以,具体而言; 1)密钥不是在.NET中生成的,而是在Java 2中)加载代码是完全相同的,当我对生成的原始私钥字节进行字节字节比较时,它们*完全相同,然后使用ImportParameters – SonarJetLens 2015-03-13 19:23:44

+0

运行Java和单声道代码的操作系统和体系结构是什么?我想知道问题是否是错误的排序。 – softwariness 2015-03-13 20:08:58

回答

0

短答复是,散列码可.NET框架版本和平台之间不同,例如32位和64位平台;或者微软和Mono之间。

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

我以前在Unity3D中开发跨平台多人游戏时遇到过这种情况。所以你需要使用你自己的散列函数,或者使用对称算法来封装你的数据。

从文档中我发现DSACryptoServiceProvider本质上是不对称的,并使用散列来创建数字签名。这里是链接: DSACryptoServiceProvider Class,阅读备注。

+0

但是使用的散列算法将是SHA1,它不依赖于对象散列代码(它不会被使用,因为这是一个字节序列的散列,而不是一个对象)......对吗? – SonarJetLens 2015-03-30 09:49:17

1

.NET框架预计某些尺寸关系以进行维护:

  • 问: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 2016-08-07 07:37:47