2012-11-26 39 views
3

我在我的項目中使用下面的代碼進行加密,一切工作正常。我如何在c#中填寫RSAParameters值?

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">ABCDEF111111111111111125FE2222222222222233333333334444</text> 
    <cipher length ="64">0000000000000000000000000000000000000000000000000000000000000000</cipher> 
</project> 

,問題是,當我導入RSAParameters值,我得到錯誤數據異常

+0

只需使用RSACryptoServiceProvider直接創建您自己的RSA密鑰對,然後使用和不使用私鑰導出參數。現在將該輸出與上述內容進行比較以查看差異。 –

回答

4

您遇到的問題是您的客戶給您的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對象。您還需要弄清楚他們想要處理的密鑰,文本和密碼數據是什麼,因爲這些數據在這個過程中會丟失。

+0

謝謝你的回答。我將如何爲P,Q,DP,DQ,逆和D生成值。 –

+0

從我所看到的您的客戶以十六進制格式爲其提供P,Q,DP,DQ,InverseA和D的XML值,所以您不需要生成任何內容,只需解析該文件即可並將這些值分配給新的RSAParameters對象的適當參數。除了代碼格式問題之外,還有 – briantyler

2

從您提供的示例結構看來,您可能(也可能不會)能夠提供的額外數據看起來像那裏。

  • 創建一個包裝類
  • 包裝性能調用轉換函數來轉換的Base64到十六進制
  • 的XmlElement屬性來控制輸出格式
  • 密碼和文本不在RSAProperties,所以客戶機將必須符合規範他們爲你

    [XmlRoot( 「項目」)] 公共類RSAWrapper { [XmlIgnore] 公共RSAParameters RsaWrap {得到;集;}

    // 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 =新的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); 
+0

... –