7

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

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 值时,我得到了 Bad Data Exception

4

2 回答 2

8

您遇到的问题是您的客户给您的 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 并RSAParameters通过将 XML 内容映射到对象上的适当字段来手动构建RSAParameters对象。您还需要弄清楚他们想要对密钥、文本和密码数据做什么,因为这些数据将在此过程中丢失。

于 2012-11-28T18:04:04.537 回答
2

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

  • 创建一个包装类
  • 用于调用转换函数以将 Base64 转换为 Hex 的包装器属性
  • XmlElement 属性控制输出格式
  • 密码和文本不在 RSAProperties 中,因此客户端必须为您指定它们

    [XmlRoot("Project")] 公共类 RSAWrapper{ [XmlIgnore] 公共 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);
于 2012-11-30T18:07:21.803 回答