如何在c#中填写RSAParameters值

时间:2012-11-26 17:29:24

标签: c# rsa public-key-encryption

我在我的项目中使用以下代码进行加密,一切正常。

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值时,我收到了错误的数据异常

2 个答案:

答案 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)

从您提供的示例结构看起来,那里有额外的数据,您可能(或可能不会)提供这些数据。

  • 创建一个包装类
  • 包装器属性,用于调用转换函数以将Base64转换为Hex
  • 用于控制输出格式的XmlElement属性
  • 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);