Как заставить WIF использовать RSA15 при шифровании данных с помощью сертификата?

Я работаю над службой WCF, которая возвращает строку в кодировке Base64, которая на самом деле является полным XML-документом ответа SAML. Поскольку эта информация будет передана поставщику, я должен выполнить его требования в отношении того, как должен выглядеть и кодироваться документ SAML. У меня возникли проблемы с получением вывода, который соответствует их требованиям.

Я знаю, что 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"/>

И им нужен раздел ‹KeyInfo›‹EncryptedKey›, чтобы показать это:

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

Я перепробовал все возможные комбинации в процедуре GetEncryptingCredentials(). Ничто не дало желаемых результатов. Самое многообещающее сообщение об ошибке, которое я получаю, выглядит так:

ID4178: EncryptingCredentials, указанные в SecurityTokenDescriptor, предназначены для асимметричного ключа. Вы должны использовать EncryptedKeyEncryptingCredentials для шифрования токена.

У кого-нибудь есть предложение? Не бойся сказать мне начать все сначала. Все в порядке. Мне просто нужно заставить это работать.

Заранее спасибо.


person NEParis    schedule 16.11.2010    source источник


Ответы (1)


Я нашел решение, которое работает. По крайней мере, он генерирует 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;
}

Просто подумал, что дам всем знать и замкну петлю на этом.

person NEParis    schedule 17.11.2010
comment
Ты крутой человек, я искал информацию о том, как правильно работать! - person JCleveland; 06.11.2013
comment
Этот пост очень старый, не уверен, что вы его помните! Ха-ха! Но разве раздел X509Data в KeyInfo не должен также включать X509Certificate? - person Naner; 09.11.2017