ComponentSpace

Forums



Processing / decrypting an Assertion containing an EncryptedID element - someone had experience /...


Processing / decrypting an Assertion containing an EncryptedID element...

Author
Message
Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
Hi all,

I have to implement a login using an eIDAS SAML compliant IdentityProvider.
The SAML response that will be received in my application will contain an "Assertion"element, that contains an "Advice" element containing an "Assertion" element containing an "EncryptedID" element. See below.

<saml:Assertion ID="_7f36d24bd635a0a6fb5cb613c4ad2b1e" IssueInstant="2020-10-28T10:24:13Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">theIssuer</saml:Issuer>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
<saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">62481a70-e1ec-4c94-8035-c9c749e9607c</saml:NameID>
 <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:SubjectConfirmationData InResponseTo="_0600bb70c974d8a1e5edf11c279b8b89" NotOnOrAfter="2020-10-28T10:26:13Z" Recipient="https://therecipient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"/>
 </saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2020-10-28T10:24:13Z" NotOnOrAfter="2020-10-28T10:26:13Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml:AudienceRestriction xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:Audience xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">theAudience</saml:Audience>
 </saml:AudienceRestriction>
</saml:Conditions>
<saml:Advice xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml:Assertion ID="_9dcad64dc438a54dd543f781bd19b84a" IssueInstant="2020-10-28T10:24:02Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">theIssuer</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">...</ds:Signature>
  <saml:Subject xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">62481a70-e1ec-4c94-8035-c9c749e9607c</saml:NameID>
  <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml:SubjectConfirmationData InResponseTo="_07a1b47ce47938222b2889bf57a14502" NotOnOrAfter="2020-10-28T10:26:02Z" Recipient="https://therecipient" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"/>
  </saml:SubjectConfirmation>
  </saml:Subject>
  <saml:Conditions NotBefore="2020-10-28T10:24:02Z" NotOnOrAfter="2020-10-28T10:26:02Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:AudienceRestriction xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml:Audience xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">theAudience1</saml:Audience>
   <saml:Audience xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">theAudience2</saml:Audience>
  </saml:AudienceRestriction>
  </saml:Conditions>
  <saml:AuthnStatement AuthnInstant="2020-10-28T10:24:02Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:AuthnContext xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:etoegang:core:assurance-class:loa4</saml:AuthnContextClassRef>
   <saml:AuthenticatingAuthority xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">00000400356767214345001</saml:AuthenticatingAuthority>
  </saml:AuthnContext>
  </saml:AuthnStatement>
  <saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <saml:Attribute Name="urn:etoegang:core:Representation" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:boolean">false</saml:AttributeValue>
  </saml:Attribute>
  <saml:Attribute Name="urn:etoegang:core:ServiceUUID" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">bfa227d1-9374-422a-bc99-e5089a9be4b2</saml:AttributeValue>
  </saml:Attribute>
  <saml:Attribute Name="urn:etoegang:core:ActingSubjectID" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:AttributeValue xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:EncryptedID>
    <xenc:EncryptedData Id="_73cae2fec8219fe17b443106d226e562" 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" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/>
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:RetrievalMethod Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey" URI="#_bd9b168a5634c520f02bf0faf7d18f48"/>
    </ds:KeyInfo>
    <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:CipherValue>Ga0SKAITz51h...</xenc:CipherValue>
    </xenc:CipherData>
    </xenc:EncryptedData>
    <xenc:EncryptedKey Id="_bd9b168a5634c520f02bf0faf7d18f48" Recipient="theRecipient" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/>
    </xenc:EncryptionMethod>
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:KeyName>ca71aba7-a6a6-4eb1-8882-17b387a01704</ds:KeyName>
    </ds:KeyInfo>
    <xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:CipherValue>CnihqV3oEmcffkbq...</xenc:CipherValue>
    </xenc:CipherData>
    <xenc:ReferenceList xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:DataReference URI="#_73cae2fec8219fe17b443106d226e562"/>
    </xenc:ReferenceList>
    </xenc:EncryptedKey>
   </saml2:EncryptedID>
   </saml2:AttributeValue>
  </saml:Attribute>
  </saml:AttributeStatement>
 </saml:Assertion>
</saml:Advice>
<saml:AuthnStatement AuthnInstant="2020-10-28T10:24:13Z" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml:AuthnContext xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">urn:etoegang:core:assurance-class:loa4</saml:AuthnContextClassRef>
 </saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
 <saml:Attribute Name="urn:etoegang:core:ServiceUUID" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
  <saml:AttributeValue xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">bfa227d1-9374-422a-bc99-e5089a9be4b2</saml:AttributeValue>
 </saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>


After decryption the content (= child element) of the element "<saml:Attribute Name="urn:etoegang:core:ActingSubjectID" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">" should now be:


  <saml2:AttributeValue xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
   <saml2:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="urn:etoegang:1.9:EntityConcernedID:Pseudo" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">[some value]</saml2:NameID>
  </saml2:AttributeValue>


Does anybody has any experience / example code / advice / tips how to decrypt this Assertion?
(my assummption is that the ComponentSpace component will not do this automatically as part of the high level api?!)

And for my tests with a dummy IdP: is there an easy way to generate such an Assertion with an EncryptedID element as part of the SAML response?

Thanks for your replies :-)

Regards,
Wouter


ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)

Group: Administrators
Posts: 2.9K, Visits: 9.5K
Hi Wouter,

The SAML high-level API handles encrypted SAML assertions but not encrypted SAML attributes or IDs. For these you would need to revert to the SAML low-level API.

Our recommendation is to encrypt the entire SAML assertion rather than individual attributes or IDs. This is the most common approach and the additional overhead is insignificant.

Is it possible to ask the IdP to encrypt the SAML assertion rather than the ID? 

If not, let me know and I'll post some sample code.

Regards
ComponentSpace Development
Wouter van de Weerd
Wouter van de Weerd
New Member
New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)New Member (18 reputation)

Group: Forum Members
Posts: 9, Visits: 55
ComponentSpace - 10/28/2020
Hi Wouter,

The SAML high-level API handles encrypted SAML assertions but not encrypted SAML attributes or IDs. For these you would need to revert to the SAML low-level API.

Our recommendation is to encrypt the entire SAML assertion rather than individual attributes or IDs. This is the most common approach and the additional overhead is insignificant.

Is it possible to ask the IdP to encrypt the SAML assertion rather than the ID? 

If not, let me know and I'll post some sample code.

Unfortunately this is not possible.
The IdP is just implementing a country wide specification for eIDAS login. See Saml Encryption for eIDAS (at the bottom of this page are some example messages)

I have already tried the low level api, to change the "normal" samlResponse that is generated by my testIdP:

private SamlResponse OnSamlResponseCreated(SamlResponse samlResponse)
{
    // Add an Advice element with a new Assertion in the samlRespponse for eIDAS
    var changedAssertion = samlResponse.GetUnsignedAssertion();

    var adviceElement = new Advice();
    var newAssertionElement = new SamlAssertion
    {
        ID = "_1010101010",
        IssueInstant = changedAssertion.IssueInstant.HasValue ? changedAssertion.IssueInstant.Value.AddSeconds(-5) : DateTime.Now,
        Issuer = new Issuer { Name = "urn:etoegang:AD:00000004003214345001:entities:9042" },
        Subject = changedAssertion.Subject, // in real eIDAS samlResponse this is different!
        Conditions = changedAssertion.Conditions, // in real eIDAS samlResponse this is different!
    };
    GetEidasStatements(newAssertionElement.Statements);

    adviceElement.AdviceList.Add(new AdviceListItem { SamlAssertion = newAssertionElement });
    changedAssertion.Advice = adviceElement;

    // Replace existing assertion with the enhanced one
    samlResponse.Assertions.Clear();
    samlResponse.Assertions.Add(new AssertionListItem {SamlAssertion = changedAssertion });
    return samlResponse;
}

private void GetEidasStatements(IList<IStatement> assertionStatements)
{
    var attributeStatement = new AttributeStatement();
    attributeStatement.Attributes.Add(new AttributeListItem { SamlAttribute = new SamlAttribute("urn:etoegang:core:Representation", "false") });
    attributeStatement.Attributes.Add(new AttributeListItem { SamlAttribute = new SamlAttribute("urn:etoegang:core:ServiceUUID", "bfa227d1-9374-422a-bc99-e5089a9be4b2") });

    // var encryptedAttribute = new EncryptedAttribute();
    //encryptedAttribute.EncryptedData = some XmlElement
    // encryptedAttribute.EncryptedData = some IEnumerable<XmlElement>

    //attributeStatement.Attributes.Add(new AttributeListItem { EncryptedAttribute = encryptedAttribute });

    assertionStatements.Add(attributeStatement);
}


But I am getting the error: "Sending an SSO response to the partner service provider has failed. System.InvalidOperationException: This document already has a 'DocumentElement' node."
And I not sure how to add the encryptedAttribute with the correct name "urn:etoegang:core:ActingSubjectID" that should contain the EncryptedID element in the AttributeValue.

So some example code would be nice :-)



ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)

Group: Administrators
Posts: 2.9K, Visits: 9.5K
Hi Wouter,

I'll get you some example code within the next 24 hours.

Regards
ComponentSpace Development
ComponentSpace
ComponentSpace
ComponentSpace Development
ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)ComponentSpace Development (4K reputation)

Group: Administrators
Posts: 2.9K, Visits: 9.5K
The following code demonstrates decrypting an encrypted ID.

This code is based off the Decrypt example console app project. It explicitly calls serviceProvider.GetService<IXmlEncryption>(). In a web application you would simply add an IXmlEncryption parameter to one of your class constructors and let the dependency injection work it out.

The xmlElement in the code below is the <EncryptedID> element you would retrieve from the SAML attribute value. I didn't show the details of accessing this.


using ComponentSpace.Saml2;
using ComponentSpace.Saml2.Assertions;
using ComponentSpace.Saml2.XmlSecurity;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Xml;

// Retrieve the IXmlEncryption using dependency injection.
var serviceCollection = new ServiceCollection();

serviceCollection.AddSaml();

var serviceProvider = serviceCollection.BuildServiceProvider();
var xmlEncryption = serviceProvider.GetService<IXmlEncryption>();

using (var x509Certificate = new X509Certificate2(certificateFileName, certificatePassword))
{
    // Load the encrypted ID from the XML element - details not shown.
    var encryptedID = new EncryptedID(xmlElement);

    using (var privateKey = x509Certificate.GetRSAPrivateKey())
    {
        // Decrypt the encrypted ID.
       var plainTextElement = xmlEncryption.Decrypt(
             encryptedID.EncryptedData,
             encryptedID.EncryptedKeys,
             privateKey);

       return new NameID(plainTextElement);
    }
}




Regards
ComponentSpace Development
GO


Similar Topics


Execution: 0.000. 2 queries. Compression Enabled.
Login
Existing Account
Email Address:


Password:


Social Logins

Select a Forum....









Forums, Documentation & Knowledge Base - ComponentSpace


Search