2010-11-16 49 views
2

我一直在做一個WCF服務,它將返回一個Base64編碼的字符串,實際上它是一個完整的SAML響應XML文檔。由於這些信息將被移交給供應商,因此我必須滿足他們對SAML文檔的外觀和編碼要求。我無法獲得滿足其要求的輸出。如何在使用證書加密數據時使WIF使用RSA15?

我知道WCF和WIF在一起應該可以幫到我。我最初使用WIF構建服務來創建SAML斷言(令牌)和其他C#代碼以生成最終的SAML文檔。除文檔的<EncryptedData>節點之外,所有這些工作都符合供應商的要求。本節使用AES256和RSAOAEP,但供應商需要AES128和RSA15。因此,我正在尋求解決辦法。任何幫助將不勝感激。

這是一個漫步。

該服務需要一個用於調用數據庫和返回字段的GUID。然後這些使用像這樣:

DataTable userData = GetDataForUser(userId); 
List<Claim> claims = new List<Claim>() 
{ 
    new Claim("ClientId", "NameOfClient") 
}; 
foreach (DataRow row in userData.Rows) 
{ 
    string memberId = row["MemberId"].ToString().Trim(); 
    string firstName = row["FirstName"].ToString().Trim(); 
    string lastName = row["LastName"].ToString().Trim(); 
    DateTime dob = Convert.ToDateTime(row["DateOfBirth"], CultureInfo.InvariantCulture); 

    claims.Add(new Claim("MemberId", memberId)); 
    claims.Add(new Claim("FirstName", firstName)); 
    claims.Add(new Claim("LastName", lastName)); 
    claims.Add(new Claim("DOB", dob.ToString("MM/dd/yyyy"))); 
} 

return claims; 

我然後創建一個像這樣的SecurityTokenDescriptor:

SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor(); 

權利要求書被添加到描述符,像這樣:

descriptor.Subject = new ClaimsIdentity(claims); 

描述符指示像這樣加密令牌:

descriptor.EncryptingCredentials = GetEncryptingCredentials(); 

和GetEncryptingCredentials()函數看起來像這樣:

private EncryptedKeyEncryptingCredentials GetEncryptingCredentials() 
{ 
    // Get the Encrypting Certificate 
    X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, "<<certificate stuff here >>", true); 

    EncryptedKeyEncryptingCredentials encryptingCreds = new EncryptedKeyEncryptingCredentials(encryptCert); 

    return encryptingCreds; 
} 

所有這一切都產生一個令牌,當寫入一個文件給了我這樣的:

<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> 
    <xenc:EncryptedData Id="_16584ace-9f3e-4352-9fc9-f6db8b2e925c" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> 
     <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" /> 
     <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> 
     <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#"> 
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"> 
      <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> 
      </e:EncryptionMethod> 
      <KeyInfo> 
      <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
       <X509Data> 
       <X509IssuerSerial> 
        <X509IssuerName><!-- value --></X509IssuerName> 
        <X509SerialNumber><!-- value --></X509SerialNumber> 
       </X509IssuerSerial> 
       </X509Data> 
      </o:SecurityTokenReference> 
      </KeyInfo> 
      <e:CipherData> 
      <e:CipherValue><!-- value -->CipherValue> 
      </e:CipherData> 
     </e:EncryptedKey> 
     </KeyInfo> 
     <xenc:CipherData><xenc:CipherValue><!-- value --></xenc:CipherValue> 
     </xenc:CipherData> 
    </xenc:EncryptedData> 
    </EncryptedAssertion> 

大,對吧?不。供應商需要<的EncryptedData >節具有以下子節點:

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/> 

而且他們需要的<的密鑰信息> <EncryptedKey>部分顯示此:

<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/> 

我想盡組合我可以在GetEncryptingCredentials()例程中想到。什麼都沒有產生預期的結果。最有前途的錯誤消息我收到這個樣子的:

ID4178:在 SecurityTokenDescriptor提供的EncryptingCredentials 是一個 非對稱密鑰。您必須使用 EncryptedKeyEncryptingCredentials到 加密令牌。

任何人有一個建議?不要害怕告訴我從頭開始。沒關係。我只需要讓這個工作。

在此先感謝。

回答

6

我發現了一個可行的解決方案。至少,它會根據需要生成XML,並且供應商表示他們能夠使用我發送的XML。

我稍微重寫了GetEncryptingCredentials()例程。它現在看起來像這樣:

private EncryptingCredentials GetEncryptingCredentials() 
{ 
    string keyWrapAlgorithm = SecurityAlgorithms.RsaV15KeyWrap; //"http://www.w3.org/2001/04/xmlenc#aes256-cbc"; 
    string encryptionAlgorithm = SecurityAlgorithms.Aes128Encryption; //"http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"; 
    int keySize = 128; 

    X509Certificate2 encryptCert = CertificateHelper.FindSingleCertificate(StoreName.TrustedPeople, StoreLocation.LocalMachine, X509FindType.FindBySubjectDistinguishedName, _settings.EncryptingCredentials, true); 

    EncryptingCredentials encryptingCredentials = new EncryptedKeyEncryptingCredentials(encryptCert, keyWrapAlgorithm, keySize, encryptionAlgorithm); 

    return encryptingCredentials; 
} 

只是想我會讓大家知道並關閉這個循環。

+0

你搖滾的人,我一直在尋找有關如何正常工作的信息! – JCleveland 2013-11-05 20:30:10

+0

這篇文章是非常古老的,不知道你是否會記得它!哈哈!但是,KeyInfo下的X509Data部分不應該包含X509Certificate嗎? – Naner 2017-11-09 15:33:59

相關問題