我在我的项目中使用以下代码进行加密,一切正常。
RSACryptoServiceProvider x_alg = new RSACryptoServiceProvider( );
// export only the public key
RSAParameters x_public_params = x_alg.ExportParameters(false);
// export the private key
RSAParameters x_private_params = x_alg.ExportParameters(true);
现在客户更改了要求,他希望将所有RSAParameters值存储到配置文件中,并提供以下详细信息用于演示
<project name="netCard Server1">
<key length="256"></key>
<D length="64">00000000000000000000000000000000000000000000000000000000000019C5</D>
<DP length="32">00000000000000000000000000000061</DP>
<DQ length="32">00000000000000000000000000000065</DQ>
<Exponent length="6">000DCD</Exponent>
<InverseQ length="32">0000000000000000000000000000003B</InverseQ>
<Modulus length="64">0000000000000000000000000000000000000000000000000000000000002C95</Modulus>
<P length="32">00000000000000000000000000000065</P>
<Q length="32">00000000000000000000000000000071</Q>
<text length ="64">0123456789ABCDEF111111111111111125FE2222222222222233333333334444</text>
<cipher length ="64">0000000000000000000000000000000000000000000000000000000000000000</cipher>
</project>
现在,问题是当我导入RSAParameters值时,我收到了错误的数据异常
答案 0 :(得分:7)
您遇到的问题是客户提供给您的XML不符合反序列化为RSAParameters
类型的对象所需的格式
我运行此代码以显示XML序列化程序生成的XML是什么样的
var provider = new RSACryptoServiceProvider();
var parameters = provider.ExportParameters(true);
var x = new XmlSerializer(parameters.GetType());
x.Serialize(Console.Out, parameters);
Console.WriteLine();
它生成的输出类似于:
<RSAParameters>
<Exponent>AQAB</Exponent>
<Modulus>ruCEpD3XnR...g/waE=</Modulus>
<P>90amUU3dDazsqN9+...jJUQ==</P>
<Q>tQv5hGehNLLmv4aC...NfUQ==</Q>
<DP>azJiiZ6itPoBQph...zBcQ==</DP>
<DQ>OmewiOw9bxi/o82...f44Q==</DQ>
<InverseQ>wNohk0NNl...YDg==</InverseQ>
<D>fNOOWp46FckcvtI+...PpXAE=</D>
</RSAParameters>
其中...是截断输出。您的客户提供的内容看起来像是超集(密钥,文本和密码不在参数列表中),但格式有点不同。
您可以要求他们以完全所需的格式提供数据,然后从中进行序列化;或者您可以接受它们的格式,将其反序列化为XML并通过将XML内容映射到RSAParameters
对象上的相应字段来手动构建RSAParameters
对象。您还需要弄清楚他们想要对密钥,文本和密码数据做什么,因为这些将在此过程中丢失。
答案 1 :(得分:2)
从您提供的示例结构看起来,那里有额外的数据,您可能(或可能不会)提供这些数据。
Cipher和Text不在RSAProperties中,因此客户端必须为您指定
[XmlRoot( “项目”)] 公共类RSAWrapper { [XmlIgnore] public RSAParameters RsaWrap {get; set;}
// replicate Key for Text and Cipher, subject to client's specs
private LenghtyValue _key = null;
[XmlElement]
public LenghtyValue Key{
get{ return (_key!=null) ? _key.Value : null;}
set{ _key = (value!=null) ? new LenghtyValue { Value = value} : null;}
}
// replicate Exponent for D, DP, DQ, InverseQ, Modulus, P and Q
[XmlElement]
public LenghtyValue Exponent{
get{
return new LenghtyValue { Value = ToHexFromB64(RsaWrap.Exponent);} // look up how to convert this
}
set {}
}
public class LenghtyValue{
[XmlText]
public string Value{get;set;}
[XmlAttribute("length")]
public int Length {get{ return (""+Value").Length;} set{}}
}
}
//然后使用上面的类: .... RSACryptoServiceProvider x_alg = new RSACryptoServiceProvider();
RSAParameters x_public_params = x_alg.ExportParameters(false); // or true
RSAWrapper wrapForClient = new RSAWrapper {
RsaWrap = x_public_params,
Key = "1024", // or whatever size you have
Cipher = "???", // whatever this field means per client specs
Text = "???", // whatever this field means per client specs
}
// with simplifications....
XmlSerializer xser = new XmlSerializer(typeof(RSAWrapper));
xser.Serialize(File.Create(yourFileName), wrapForClient);