我有一份相同的代码在Mono (Unity 4.5)和MS .NET下编译和运行:
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实现和Mono的实现方式有所不同?
更多信息:
- 密钥在Java中生成,并在转换为DER格式以与.NET兼容后进行导出 - 使用BinaryReader从磁盘加载密钥,并将整数值加载为byte []到DSAParameters(P,Q,G和X)中 - 公钥在Java应用程序中加载,该应用程序使用Oracle实现来验证签名 - 所有C#代码都是“对称”的,即在Mono和MS .NET应用程序中使用相同
更新2:
今天早上我再次尝试了一下,同样的.NET应用程序在Mac上运行(使用Mono Develop,普通香草),在Windows上运行(Visual Studio 2010)。加载相同的私钥字节,相同的代码路径(至少就C#而言)——只有在Windows上才会出现“bad data”异常。以下是密钥:
P: 17801190547854226652823756245015999014523215636912067427327445031444286578873
70207706126952521234630795671567847784664499706507709207278570500096683881440341
29745221171818506047231150039301079959358067395348717066319802262019714966524135
060945913707594956514672855690606794135837542707371727429551343320695239
Q: 864205495604807476120572616017955259175325408501
G: 17406820753240209518581198012352343653860449079456135097849583104059995348845
58231478515974089409507253077970949157594923683005742524387610370844734671801488
76118103083043754985190983472601550494691329488083395492313850000361646482644608
492304078721818959999056496097769368017749273708962006689187956744210730
X: 3505625379966178555918512548923624458026758122
...
DSACryptoServiceProvider
中的字节序问题,而不是从文件加载参数时的字节序(即进入ImportParameters
的字节相同,但被该方法解释不同),但这可能并不是原因。关于.NET限制值,这是有可能的,或者它可能是一个错误。您能否提供一些示例参数的十六进制或base64格式,这些参数无法导入到.NET中,以便我尝试复现它? - softwariness