问题
I have been working on a WCF service which will return a Base64 encoded string which is, in reality, a full SAML response XML document. Because this information will be handed off to a vendor, I have to meet their requirements for how the SAML document will look and be encoded. I am having trouble getting an output which meets their requirements.
I know WCF and WIF together should help me. I originally built the service using WIF to create the SAML Assertions (token) and other C# code to generate the final SAML document. All of this works and meets the vendor's requirements except for the <EncryptedData> node of the document. This section uses AES256 and RSAOAEP but the vendor wants AES128 and RSA15. Thus, I am hunting for a resolution. Any help would be greatly appreciated.
Here is a walk through.
The service takes in a GUID which is used to call the database and return fields. These are then used like so:
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;
I then create a SecurityTokenDescriptor like this:
SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor();
The claims are added to the descriptor like so:
descriptor.Subject = new ClaimsIdentity(claims);
The descriptor is instructed to encrypt the token like this:
descriptor.EncryptingCredentials = GetEncryptingCredentials();
and the GetEncryptingCredentials() routine looks like this:
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;
}
All of this generates a token which, when written to a file gives me this:
<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>
Great, right? Nope. The vendor needs the <EncryptedData> section to have the following child node:
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
And they need the <KeyInfo><EncryptedKey> section to show this:
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
I have tried every combination I can think of within the GetEncryptingCredentials() routine. Nothing has produced the desired results. The most promising error message I receive looks like this:
ID4178: The EncryptingCredentials provided in the SecurityTokenDescriptor is for an asymmetric key. You must use an EncryptedKeyEncryptingCredentials to encrypt the token.
Anyone have a suggestion? Don't be afraid to tell me to start all over. That's all right. I just need to get this to work.
Thanks in advance.
回答1:
I found a solution which works. At least, it generates the XML as I need it to and the vendor has said they are able to use what I am sending them.
I rewrote the GetEncryptingCredentials() routine slightly. It now looks like this:
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;
}
Just thought I would let everyone know and close the loop on this.
来源:https://stackoverflow.com/questions/4196278/how-do-i-make-wif-use-rsa15-when-encrypting-data-using-a-certificate