2013-07-03 63 views
7

Tôi đã quản lý để mã hóa và giải mã tài liệu xml bằng các ví dụ trên MSDN. http://msdn.microsoft.com/en-us/library/ms229744.aspxhttp://msdn.microsoft.com/en-us/library/ms229943.aspxMã hóa và giải mã XML cho nhiều người nhận có chứng chỉ X509

Điều này được thực hiện theo tiêu chuẩn mã hóa XML W3C (XML Enc).

Tất cả đều hoạt động tốt. Vấn đề của tôi là một tài liệu xml dành cho 2 hoặc 3 người nhận. Tôi muốn mã hóa cùng một xml với nhiều khóa (khóa công khai chứng chỉ X509) để tài liệu có thể được giải mã bởi nhiều người nhận.

Điều này là tất cả có thể theo tiêu chuẩn mã hóa XML W3C bằng cách sử dụng nhiều phần tử EncryptionKey có chứa khóa phiên đối xứng được mã hóa.

Tôi không thể tìm thấy bất kỳ ví dụ nào về cách đạt được điều này trong. Net sử dụng các lớp mã hóa tiêu chuẩn.

Điều này phải được triển khai trong .NET C#.

Có cách nào để thực hiện ví dụ này hoặc mã ở đâu đó không?

+0

Chào mừng bạn đến với Stackoverflow và cảm ơn câu hỏi thú vị. Hãy hy vọng ai đó với đủ kiến ​​thức .NET có thể trả lời nó. Lưu ý rằng bạn nên luôn luôn bao gồm một thẻ ngôn ngữ. Bạn không cần phải đặt ngôn ngữ trong tiêu đề mặc dù. –

+0

Tôi thậm chí không phải là nhà phát triển C#, nhưng tôi nghĩ Stackoverflow nên biết điều này ... –

+0

Tôi không nghĩ rằng đó là một ý tưởng hay: http://arstechnica.com/business/2011/10/researchers-break-w3c-encryption -standard-for-xml /, đây là [paper] (http://www.nds.ruhr-uni-bochum.de/media/nds/veroeffentlichungen/2011/10/22/HowToBreakXMLenc.pdf). –

Trả lời

4

Lớp EncryptedElement có thể lấy bao nhiêu EncryptedKeys tùy thích. Chừng nào cho bên kia một cách chính xác có thể xác định EncryptedKey của họ (bằng cách sử dụng người nhận hoặc các yếu tố KeyInfoName), bạn không nên có bất kỳ vấn đề:

// example xml 
XmlDocument xdoc = new XmlDocument(); 
xdoc.PreserveWhitespace = true; 
xdoc.LoadXml(@"<root><encryptme>hello world</encryptme></root>"); 

var elementToEncrypt = (XmlElement)xdoc.GetElementsByTagName("encryptme")[0]; 

// keys 
// rsa keys would normally be pulled from a store 
RSA rsaKey1 = new RSACryptoServiceProvider(); 
RSA rsaKey2 = new RSACryptoServiceProvider(); 
var publicKeys = new[] { rsaKey1, rsaKey2 }; 

string sessKeyName = "helloworldkey"; 
var sessKey = new RijndaelManaged() { KeySize = 256 }; 

// encrypt 
var encXml = new EncryptedXml(); 
var encryptedElement = new EncryptedData() 
{ 
    Type = EncryptedXml.XmlEncElementUrl, 
    EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url), 
    KeyInfo = new KeyInfo() 
}; 
encryptedElement.CipherData.CipherValue = encXml.EncryptData(elementToEncrypt, sessKey, false); 
encryptedElement.KeyInfo.AddClause(new KeyInfoName(sessKeyName)); 

// encrypt the session key and add keyinfo's 
int keyID = 0; 
foreach (var pk in publicKeys) 
{ 
    var encKey = new EncryptedKey() 
    { 
     CipherData = new CipherData(EncryptedXml.EncryptKey(sessKey.Key, pk, false)), 
     EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url), 
     Recipient = string.Format("recipient{0}@foobar.com", ++keyID), 
     CarriedKeyName = sessKeyName, 
    }; 
    encKey.KeyInfo.AddClause(new KeyInfoName(encKey.Recipient)); 
    encryptedElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(encKey)); 
} 

// update the xml 
EncryptedXml.ReplaceElement(elementToEncrypt, encryptedElement, false); 

// show the result 
Console.Write(xdoc.InnerXml); 
Console.ReadLine(); 
Console.WriteLine(new string('-', 80)); 

Tạo

<root> 
    <EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"> 
     <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" /> 
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
      <KeyName>helloworldkey</KeyName> 
      <EncryptedKey Recipient="[email protected]" xmlns="http://www.w3.org/2001/04/xmlenc#"> 
       <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> 
       <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
        <KeyName>[email protected]</KeyName> 
       </KeyInfo> 
       <CipherData> 
        <CipherValue>bmVT4SuAgWto6NJoTnUhrwaQ5/bWx39WKfs8y/QEQbaEBqdvl2Wa3woQGZxfigZ2wsWZQJFW0YGMII0W6AATnsqGOOVEbdGxmnvXRISiRdhcyNHkHot0kDK987y446ws5CZQQuz8inGq/SNrhiK6RyVnBE4ykWjrJyIS5wScwqA=</CipherValue> 
       </CipherData> 
       <CarriedKeyName>helloworldkey</CarriedKeyName> 
      </EncryptedKey> 
      <EncryptedKey Recipient="[email protected]" xmlns="http://www.w3.org/2001/04/xmlenc#"> 
       <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /> 
       <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
        <KeyName>[email protected]</KeyName> 
       </KeyInfo> 
       <CipherData> 
        <CipherValue>oR8NPTm1NasWeDXBjayLk+p9/5RTWOZwNJHUMTQpZB9v1Aasi75oSjGqSqN0HMTiviw6NWz8AvHB9+i08L4Hw8JRDLxZgjaKqTGu31wXmM3Vc0CoYQ15AWMZN4q4tSxDhwuT8fp9SN+WFBm+M3w3bcPoooAazzDHK3ErzfXzYiU=</CipherValue> 
       </CipherData> 
       <CarriedKeyName>helloworldkey</CarriedKeyName> 
      </EncryptedKey> 
     </KeyInfo> 
     <CipherData> 
      <CipherValue>ohjWIEFf2WO6v/CC+ugd7uxEKGJlxgdT9N+t3MhoTIyXHqT5VlknWs0XlAhcgajkxKFjwVO3p413eRSMTLXKCg==</CipherValue> 
     </CipherData> 
    </EncryptedData> 
</root> 

Để giải mã các tài liệu, bạn phải cung cấp một ánh xạ giữa tên khóa và chìa khóa riêng của chứng chỉ:

// Decrypt 
string myKeyName = "[email protected]"; 

// specify we want to use the key for recipient1 
var encryptedDoc = new EncryptedXml(xdoc); 
encryptedDoc.AddKeyNameMapping(myKeyName, rsaKey1); 
encryptedDoc.Recipient = myKeyName; 

// Decrypt the element. 
encryptedDoc.DecryptDocument(); 

// show the result 
Console.Write(xdoc.InnerXml); 
Console.ReadLine(); 

Kết quả:

01.
<root><encryptme>hello world</encryptme></root> 
+1

Tôi sẽ đợi bản án của người yêu cầu ban đầu, nhưng điều này có vẻ tốt. Tôi hơi ngạc nhiên về các không gian tên (digsig?), Nhưng hai người nhận trong 'SignedInfo' ... Có lẽ là vậy. –

+0

Điều này rất giống với giải pháp tôi đã thử, nhưng tôi nhận được một ngoại lệ nếu tôi cố gắng giải mã bằng cách sử dụng tên khóa thứ 2 thay vì tên khóa thứ nhất. Tôi đã thử mã của bạn và dường như có cùng một vấn đề. – RogerN

+1

@RogerN, có vẻ như tôi thiếu một phần tử KeyInfo. Bạn cũng phải chỉ định trường Người nhận trên đối tượng EncryptedXml khi giải mã. Nên được cố định ngay bây giờ. – Mitch

Các vấn đề liên quan