William's profile.Net ZoneBlogLists Tools Help
    January 24

    Create SecurityContextTokens without X509 Certs

    So I wanted to roll my own SecurityContextToken (SCT) service.  Not because I want to reinvent the wheel, but because I did not want to have to use X509 certs and because I could not figure out how to issue SCTs using soap.tcp at the server.  All the documentation addresses using IIS web service and ASP.  First a word on SCTs as they can be a bit confusing.

    The goal is to authenticate to the server and get a SCT at both sides.  The idea is you can only get a SCT if you authenticate at the server.  The SCTs at both sides have a random 16 byte “secret” key that both sides can use to encrypt the rest of the session (using AES/Rijndael or other.)  This is very similar to how SSL works.  SCTs are a bit more flexible as you don’t have to encrypt all parts of the conversation, only those parts that need encryption, so it is an opt-in model.  The interesting feature is that once the SCT is cached at the server side, you can send messages with only the SCT header in the message and the server can verify you already authenticated so you don’t need to keep sending a UsernameToken (UT).  However, you *should encrypt and/or sign each message with the SCT, so that the server can verify your SCT “knows” the secret key.  Otherwise anyone could construct a SCT using the same SCT.Identifier and can access  your Web method, as only the Identifier string is sent in the header.  At the server, the SCT also maps to an authenticated UsernameToken so that your methods can verify Role memberships and have access to the username, etc.  In WSE, you can use the SecurityContextTokenServiceClient class to request a SCT from a URL.  However this requires a server side X509 certificate.  I wanted a secure solution that did not require a cert, but still used secure PKI to negotiate the SCT.

    This method resembles the built-in method, but requires only a standard RSA key pair as created with the RSACryptoServiceProvider class in the .Net framework.  If you sign your assemblies with a strong name (SN), then you already have everything you need.  The server private key needs to be secured as normal.  The client’s public key is already in the assembly for ready access to create an RSA object from it.  This does require that the client calling your web service actually is running your client assembly.  If this is not the case, the client could also get the public key via some prior out-of-band method such as email, diskette, etc.  You don’t want to allow the client to get the public key via a network call as a third party could do a Man-In-Middle attack by returning their own public key to your client.  This is the reason server Certs where created in the first place to prove to the client that you got the correct key and not some other key by an attacker.  As we "know" the server's public key already, we can avoid having to use Certs for this proof.  If you did want to get Public key using a network call, you would need to return a Cert or have some prior security context setup between the you and the server.  Anyway, here is the process:

    1)      Client creates public RSA object from public key of service.
    2)      Client generates random entropy (secret) bytes (k1) to be used as part of the shared session key (i.e. the SCT.KeyBytes value).
    3)      Client creates a new RSA key pair (i.e. clientRSA) to be used for the key exchange.
    4)      Client creates a message containing Key entropy bytes, user name, password, and the public key from clientRSA.  Client encrypts Key, user name, password, and public key fields using server’s public key from step 1.  Request is Signed.
    5)      Server method gets message.  Server verifies signature and decrypts all fields to get the clear data.
    6)      Server authenticates user using any method desired at the server.  I will use Win32’s LogonUser API to leverage Windows authentication so I don’t need another out-of-band user database.  You could, however, use your own database.  A UsernameToken is created (but not cached.)
    7)      The server generates its’ random entropy bytes (k2) and combines them with the client’s “k1” bytes to generate a shared session key (sKey).
    8)      The server creates a new SCT and sets the KeyBytes to the sKey.  The SCT is created with the UT passed to the constructor.
    9)      The server generates a reply.  It adds “k2”, SCT.Identifier string, Expire date, and UT ID string to the message and encrypts the “k2” bytes using the public RSA key passed in the client request message.  Server also adds a Key Verifier hash so client can verify they both use same key.  The server also signs the reply so the client can verify it came only from the server.  The server also caches the SCT.
    10)  The client gets the reply and verifies the signature.  It decrypts the “k2” key and generates “sKey” itself.  It then creates a new SCT using “sKey” and the Identifier passed from the server reply and verifies the KeyVerifier (Note the Identifiers have to match so the server can find the SCT in the cache).
    11)  Client can now sign and encrypt future messages using just the new SCT (i.e. no UT required).  The SCT can be used until it expires, however it is probably good practice to get a new SCT for each unique session or set of related method calls.

    Now that client has its new SecurityContextToken, it should keep it for the rest of the session and *only use the SCT or a DerivedKeyToken (DKT) derived from the SCT.  The UT is not needed or desired.  The client should also *always encrypt or, at a minimum, sign all outgoing messages with the SCT or DKT.  This is because the server can only verify you know the SCT shared key, if you sign or encrypt the message.  We don’t need to keep attaching the UT in the Soap header because that would be redundant and just overhead.   The SCT is already authenticated, so use that.  We can also add consistency and security to all our web method if we always *require a SCT in the header.  That way WSE automatically verifies the SCT, any hash, or decryption for us.  We do, however, still need to assert in our methods (or in Policy) that a SCT was attached, and the body was signed (or encrypted as needed).  As a rule, I would always require a body signature was attached.  As noted, after we get our SCT, we can forget about any UTs.  We don’t need to send them and should not (unless you have some specific need.)  If you do need to attach a UsernameToken to a Soap header – always encrypt it using the SCT.  The protocol summary is as follows:

    C->S
        {K1, Username, password, C’s public key}S’s public key
        {digest[K1, Username, password, Mod1, Mod2, Exp]}C's private key

    C<-S
       
    {K2}C’s public key
       
    UT.ID
       
    SCT.Identifier
       
    SCT.Expires
        KeyVerifier
       
    {digest[K2, UT.ID, SCT.Identifier, SCT.Expires, KeyVerifier]}S’s private key

    Client (C) sends K1, Username, password, and C’s public key to Server (S).  All elements are encrypted with S’s public key.  Server creates SCT with generated sKey and returns K2, UT.ID, SCT.Identifier, SCT.Expires, KeyVerifier and Signature.  K2 is encrypted with C’s public key.  All elements are hashed and then signed using S’s private key.  Client can then verify all elements have not been changed and message sent by S.  Client generates sKey and SCT.

    That is about it.  We now have a way to securely pass user credentials to the server and get a SCT in reply using soap.tcp and PKI.  UsernameTokens are then out of the picture so we don’t have to worry about SendPlainText or SendHash stuff anymore.  To keep this post ~short, I will show the implementation at Get SecurityContextToken C# Code .  Also note, this implementation is updated at Updated Get SecurityContextToken in C#. Cheers!

    --
    William

    Comments (11)

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    No namewrote:
    http://www.batteryfast.co.uk/compaq/336962-001-battery.php Laptop Battery for compaq NX7000 NX7010 ZT3000 X1000 X1100 laptop battery,
    http://www.batteryfast.co.uk/compaq/233336-001-battery.php NEW Battery For Compaq Presario 2700 Evo N180 233336-001 laptop battery,
    http://www.batteryfast.co.uk/dell/942rv-battery.php Battery for 942RV 312-7209 DELL Inspiron 2000 2100 2800 laptop battery,
    http://www.batteryfast.co.uk/dell/w2391-battery.php Dell 8500 8600 8600c D800 M60 8N544 2P690 4P227 battery laptop battery,
    http://www.batteryfast.co.uk/dell/bat30wl-battery.php 6.6Ah Battery fits BAT30WL DELL Inspiron 5000 5000e laptop battery,
    http://www.batteryfast.co.uk/dell/1g222-battery.php Laptop Battery for Dell Inspiron 2600 2650 1G222 BAT3151L8 laptop battery,
    http://www.batteryfast.co.uk/dell/c400-battery.php New Battery for Dell Latitude C400 9H350 312-4609 laptop battery,
    http://www.batteryfast.co.uk/dell/310-5351-battery.php New GENUINE Dell Latitude D810 M70 Y4367 Battery laptop battery,
    http://www.batteryfast.co.uk/dell/312-0315-battery.php NEW DELL BATTERY D410 W6617 HIGH CAPICITY VERSION Y6142 laptop battery,
    http://www.batteryfast.co.uk/dell/300m-battery.php 4400mAh battery fits DELL Latitude X300 Inspiron 300M laptop battery,
    http://www.batteryfast.co.uk/dell/d420-battery.php 5.8Ah Laptop Battery fit DELL Latitude D420 D430 KG046 laptop battery,
    http://www.batteryfast.co.uk/dell/dl1420lp-battery.php battery for DELL Inspiron 1420 FT080 WW116 NEW laptop battery,
    http://www.batteryfast.co.uk/dell/dl1520lp-battery.php Dell 1720 1721 1520 Vos 1500 1700 Battery FK890 UW280 laptop battery,
    http://www.batteryfast.co.uk/dell/7012p-battery.php NEW battery fits P N 7012P Dell Latitude CS CSi CSx laptop battery,
    http://www.batteryfast.co.uk/hp/336962-001-002-battery.php Battery fits HP Pavilion zt3000 zt3010US 337607-001 laptop battery,
    http://www.batteryfast.co.uk/hp/nc4000-battery.php 8.8ah GENUINE HP 381373-001 383510-001 HSTNNIB12 PB991A laptop battery,
    http://www.batteryfast.co.uk/hp/hstnn-ob53-battery.php laptop battery for HSTNN-OB53 447649-321 B1216TU laptop battery,
    http://www.batteryfast.co.uk/hp/m62044l-battery.php HP COMPAQ Compaq Presario B3000 B3800 Series laptop battery,
    http://www.batteryfast.co.uk/hp/pp2182l-battery.php NEW Battery for HP ZD7000 NX7900 NX9500 12-cell PP2182D laptop battery,
    http://www.batteryfast.co.uk/hp/b2800-battery.php Battery for Compaq hp 405231-001 407672-001 HSTNN-CB25 laptop battery,
    http://www.batteryfast.co.uk/hp/nc2400-battery.php New Compaq 2510p NC2400 Laptop Extended Battery EH768AA laptop battery,
    http://www.batteryfast.co.uk/ibm/02k7055-battery.php Laptop Battery 02K6928 02K7055 for IBM Thinkpad R32 R40 laptop battery,
    http://www.batteryfast.co.uk/mitac/8050-battery.php Battery For Packard Bell EasyNote BP-8050(P) 40006487 laptop battery,
    http://www.batteryfast.co.uk/mitac/8060-battery.php Mitac MiNote 8060 Li-Ion Replacement Battery laptop battery,
    http://www.batteryfast.co.uk/sony/pcga-bp2sa-battery.php Battery For Sony PCGA-BP2S PCGA-BP2SA VAIO PCG-SR17 NEW black laptop battery,
    http://www.batteryfast.co.uk/sony/pcga-bp2sa-002-battery.php grey Battery For Sony PCGA-BP2S PCGA-BP2SA VAIO PCG-SR17 NEW laptop battery,
    http://www.batteryfast.co.uk/sony/vgp-bps2a-002-battery.php 7.2ah LAPTOP BATTERY SONY VAIO VGP-BPS2 VGP-BPS2B VGP-BPS2A black laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3010u-1bar-battery.php Battery For Toshiba 8000 PA2451URN PA2510UR PA3010U laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3098u-1bas-battery.php Battery For TOSHIBA Satellite 1200 3000 3005 PA3098U laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3331u-1brs-battery.php Laptop Battery TOSHIBA Satellite PA3331U M30 laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3009ur-battery.php battery fits Toshiba PA3009UR-1BAR Tecra 8100 PA3009 laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3166u-1bas-battery.php 6.6ah Battery for Toshiba B491 PA3166U laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3382u-1brs-002-battery.php 6.6ah Battery Fit Toshiba PA3382U-1BRS PA3384U-1BRS laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3291u-battery.php New battery for TOSHIBA P20 P25 PA3291U-1BRS 6600mAh laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3356u-1brs-002-battery.php 8.8ah Battery TOSHIBA PA3356U-1BAS PA3356U-1BRS PA3356U-2BRS laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3335u-1bas-battery.php battery fits TOSHIBA PA3399U-1BAS PA3399U-1BRS 6600mAH laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3534u-1brs-battery.php NEW Genuine Toshiba Battery Satellite PA3534U-1BRS A205 laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3534u-1brs-002-battery.php Original Battery Toshiba PA3534U-1BRS PA3534U-1BAS NEW laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3536u-1brs-battery.php New PA3536U Battery for Toshiba Satellite P200 P205 laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3536u-1brs-002-battery.php 6.6ah New PA3536U Battery for Toshiba Satellite P200 P205 laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3062u-1bar-battery.php New Genuine Toshiba Tecra 8200 Battery PA3062U-1BAR laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3369u-battery.php laptop battry for PA3369U-1BAS laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3055u-battery.php NEW battery fits Toshiba Satellite 1700 PA3055U-1BAS laptop battery,
    http://www.batteryfast.co.uk/toshiba/pa3210u-battery.php NEW Toshiba Satellite 1110 1115 4500mAh Battery PA3210U laptop battery,
    http://www.batteryfast.co.uk/dell/Latitude-131L.htm dell Latitude 131L battery,
    http://www.batteryfast.co.uk/dell/Vostro-1000.htm dell Vostro 1000 battery,
    Dec. 17
    No namewrote:

    Hi,Do you have used LCDs, second hand LCDs, used flat screens and used LCD monitors? Please go here:www.sstar-hk.com(Southern Stars).We are constantly buying re-usable LCD panels and working for LCD recycling.The re-usable panels go through strictly designed process of categorizing, checking, testing, repairing and refurbishing before they are re-used to make remanufactured LCD displays and TV sets.Due to our recent breakthrough in testing and repairing technology of LCD, we can improve the value for your LCD panels. website:www.sstar-hk.com[cibfeadcadajbcf]

    Oct. 26
    No namewrote:
    wow gold!All wow gold US Server 24.99$/1000G on sell! Cheap wow gold,wow gold,wow gold,Buy Cheapest/Safe/Fast WoW US EU wow gold Power leveling wow gold from the time you wWorld of Warcraft gold ordered! wow power leveling wow power leveling power leveling wow power leveling wow powerleveling wow power levelingcheap wow power leveling wow power leveling buy wow power leveling wow power leveling buy power leveling wow power leveling cheap power leveling wow power leveling wow power leveling wow power leveling wow powerleveling wow power leveling power leveling wow power leveling wow powerleveling wow power leveling buy rolex cheap rolex wow gold wow gold wow gold wow gold -49656975148254
    June 3
    Picture of Anonymous
    William wrote:
    "The Utils class doesn't have RijndaelDecrypt and other relevant method. Can you post it or send it to me. "

    Sure. Posted at new blog entry here:
    http://spaces.msn.com/members/staceyw/Blog/cns!1pnsZpX0fPvDxLKC6rAAhLsQ!303.entry

    --William
    Mar. 6
    Picture of Anonymous
    Mohan wrote:
    William,

    Thanks for posting the code. The Utils class doesn't have RijndaelDecrypt and other relevant method. Can you post it or send it to me.

    Thanks,
    mohan
    Mar. 5
    Picture of Anonymous
    William wrote:
    --Matt: "Do you know of a simple way in which we can hook back into the wse UsernameToken authentication mechanism at the point the UsernameToken is created on the server? "

    In my example, not sure what that would provide (please expand the need). As you get the clear password, you can auth or not auth anyway you like. Plus, I don't think you want to cache the UT, just the SCT, and the custom UTM would cache it. This does not stop you, however, from having a custom UsernameToken manager installed, to handle any requests that just have UsernameTokens. However I think I would *require all SCT tokens to keep a better box around security and add consistency. As for policy, you could just require all methods are signed by a authenticated SCT and the only way to get one is via your one server method (i.e. the *only method that does not require a SCT token signature.) Maybe I did not understand your need. If so, please post back and I can chew on it some more. Cheers :-)

    -- William
    Jan. 31
    Picture of Anonymous
    Matt Bishop wrote:
    Many thanks for this - cured more than a few headaches! We currently have your scheme running with no problems using http and policy for SCT usage. In order for policy to work, we did have to add the following to the server code at the point the SCT is created:

    sct.TokenIssuer = HttpContext.Current.Request.Url;

    and the following to the client at the point the SCT is created:

    sct.TokenIssuer = new Uri(wseTokenService.Url);

    where wseTokenService is a standard VS generated web service proxy. It may be that these changes needed because of <wssp:TokenIssuer>http://...</wssp:TokenIssuer> elements in the policy, but I haven't tested for that.

    Do you know of a simple way in which we can hook back into the wse UsernameToken authentication mechanism at the point the UsernameToken is created on the server? This would allow a custom UsernameToken manager to specified in the .config file rather than the authentication logic being part of the sct generation flow...
    Jan. 31
    Picture of Anonymous
    William wrote:
    I played with Diffie-Hellman and SRP for key exchanges using WSE and got code working. The problem with DH is that to prevent the man-in-the-middle attack, you need std PKI or Cert. Then you probably need two 2-way exchanges. As long as we need PKI, we may as well do it this way with one request/reply. SRP is great, but requires a seperate DB to store the verifier/username. Not bad if that is all you want, but if you wanted WinLogon, then you have to have both DB and Windows User DB. You could use SRP just for the key exchange with a default account just for key exchange, but not sure I like that.

    My method could be easily modified to use a default user/pw just to create an un-authenticated shared key token. Then you could use that with normal WSE to encrypt and sign the next message pair. I am thinking more on that as an addition option. As the SCT would be cached but not authenticated, you would need to watch that you don't allow any SCT into your Web Methods, only Authenticated ones. --William
    Jan. 25
    Picture of Anonymous
    mvptools wrote:
    Thanks to both. I have this implemented in c# today. Was just looking it over (and over) to find weakness. I am going to update a bit with Signature on Request using Client's private key. As it stands right now, a man in the middle could get *half the key but not all. I think the client sig will not allow even half the key. He would still need the username, password and the other half of the random key. So it is still pretty good as it. I will hope to post code today sometime. Please feel free to comment on any code/protocol weakness. Cheers!
    Jan. 25
    Picture of Anonymous
    Colin Anderson wrote:
    Like the previous commenter, I too have been planning on trying this out (I've seen other applications doing this). I want to keep the logistics and problems associated with distributing certificates to a minimum.

    I look forward to seeing your code for this!
    Jan. 25
    Picture of Anonymous
    Softwaremaker wrote:
    Ahhh...

    You beat me to it :) I knew something like that would be very useful and there are tons of requests out there for the use of SCT without X.509 because of cost issues or the server admin doesnt want to install them for whatever reasons.

    I was on my way to implementing it, then I took some time off to look at the specifications for the exchange of entropy values, then I got derailed by some work committments and after that I just got lost...

    It is so good for you to come up with this. It is excellent. I would have to try it and feedback. Many people will thank you for it.
    Jan. 25