Changes

Jump to: navigation, search

Identity/AttachedServices/KeyServerProtocol

12,242 bytes added, 01:25, 3 July 2013
Client-Side SRP Calculation
[[File:PICL-IdPAuth-main-KDF.png|masterKey KDF]]
== Client-Side SRP Calculation Protocol Details ==
The PiCL client uses the SRP protocol (TBD) Thishttp://srp.stanford. is kind of crazy so far. The picture is incomplete and needs more detailedu/) to prove that it knows the account password without revealing the actual password (or information enabling a brute-force attack) to the server or any eavesdroppers.
The server should SRP is somewhat underspecified. We use Jed's SRP module from https://github-6a, with SHA256 as the hash, and the 2048-bit modulus defined RFC 5053 Appendix A.com/jedp/nodeWe consistently zero-srp pad all string values to 256 bytes (2048 bits), and use H(A+B+S) as the key-confirmation message "M1". These details, plus the SRP design papers and RFCs 2945 and 5054, should be enough to build a compatible implementation. The diagrams below are annotated with test vectors to verify compatibility.
[[FileThe server should use Jed's SRP module from https:PICL-IdPAuth//github.com/jedp/node-srp . The client-SRPmight use SJCL (http://crypto.stanford.edu/sjcl/) or native code (NSS).png|client-side SRP]]
The basic idea is that we're using the main-KDF output "srpPW" as a password for the SRP calculation. We use the email address for "identity", and a server-provided string for "salt". (We could safely leave them blank, since equivalent values are already folded into the password-stretching process, but it's less confusing to follow the SRP spec and fill them in with something sensible).
The Note that SRP -6a uses a "gk" value which basically encodes the group being used (generator) "N" and "Ng" (prime modulus) should . Since all PICL accounts use the same 2048-bit group, they will all use the same "k" value from RFC 5054 Appendix A, which is also used in SRP. Clients should (not accept arbitrary g/N values (to protect against small primes, nonbe confused with the per-primes, and nonsession shared-generatorssecret "K" key that emerges from the protocol). In the future we might allow alternate parameter sets, in which case the serverThis group's first response should indicate which parameter set to use."k" integer is (as a base-10 number):2590038599070950300691544216303772122846747035652616593381637186118123578112
The following examples use a non-ascii email address of "andre@example.org" (with an accented "e", UTF8 encoding is 616e6472c3a9406578616d706c652e6f7267) and a non-ascii password of "password" (with accents on "a" and "o", UTF8 encoding is 70c3a4737377c3b67264). Given the password-stretching described earlier, this results in an srpPW of:5b597db713ef1c0567f8d053e9dde294f917a0a838ddb661a98a67a188bdf491 === SRP Verifier Calculation === When the client first creates the account, it must combine the account email address, the password, and a randomly-generated srpSalt, to form the srpVerifier: [[File:PICL-IdPAuth-SRP-Verifier.png|client-side SRP Verifier calculation]] Given the sample email and password above, the SRP Verifier calculation yields the following. (Note: the srpSalt is normally generated randomly, but for illustrative purposes, here we used fixed pre-calculated values). * srpSalt (hex string): 00f1000000000000 0000000000000000 0000000000000000 000000000000009b* x (internal, as a hex string): ffd36e11f577d312892334810d55089cb96c39443c255a9d85874bb6df69a537* x (internal, as decimal integer): 115713340795669212831971819661984296758573939625477265918747447380376082294071* v (internal, decimal integer): 71059715947322363168818619231596014948502664753879821526306672648301269136332546839100253983803912725413731153916626297948231925131054776204301203872383833825292863403260680360596134078965569670569235971894130915251144385164054999200238790399524380121634022271328529734937174066811503227222944678351915275352511787735824142082281320032065951325711784707869987141733046865019265053926187756870781628009053137574167426864838849814321621297918109241151570638074596222682772158532484976644908876686423788254204401136102193244276625617385185761349298945899736743346225452678822123821266140913290180513540399852050747986* srpVerifier (hex string):00901a4e05a7986c fafe2c80993f6e21847d38b8b9168065 149480722d008c9ac5fe418d799d03c2 b1c26db2afcd45130a0601d310faa060 cc728888aba130a17d855773107ecc92 f31ea3a3838bc72777fc26420ed59918 298583d15640b965939dd6967e943bd6 ed846dbbb18885c74f6e9370e4eeecc4 c8e2a648850cf2ba5baab18888b433c4 b0bd8891eeffe16cc022a098284696bc 3a81e735a1a2a37162f62b980879bbd4 03ae55548b9feeecb18bf0740f0d078a 435fedb5324d630e8a14fed435fbb5ea 4b6e94b8b129799d2a0991671a67be34 149dc5e94a4a3d05749fc3b9e1a53282 96b20a15348420bed2f28d2558cb4099 f30be8a7240c9252  The client sends srpSalt and srpVerifier to the server when it creates the account. It will also re-compute the 'x' value (as an integer) during sign-in. The server will convert the srpVerifier string back into an integer ('v') for use during its own sign-in calculations. === SRP Server-side Sign-In Flow === When the user connects a new device to their account, they use the getToken1() API to start the SRP protocol. This sends the account email address to the server. The server looks up the stored srpVerifier for this account, creates a random 'b' integer, performs some math to compute the "B"number, then converts Binto a string known as "srpB". " value according srpB" is returned to the client, along with srpSalt and the key-stretching parameters. "b" and "srpB" are retained for the subsequent getToken2() call. Note that it is critical that the "b" integer remain secret on the server. [[File:PICL-IdPAuth-SRP-Server.png|server--side SRP protocol ]] * b (hex integer, normally random but pre-calculated for this example): 00f3000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0000000000000020* b (as decimal integer):119827766042000957856349411550091527197081252269605447689936430952278002910536155503035277450562560602971778328003253459733139844872578335969641434172163891575825549320284149937367218831553428069327423189198736863575142046053414928395487318790431357183095397064892915732142348352729476798883594253343430842313006332606344714480994398088610693164826214242314090883070476916770009839296811772743420990997238759832829219109897328764288319854878234173127723999262829546938957845836323714648638545526799188280210660508721582004031026248318155961400949332162983284562611677708050444470403904739431335617585333671378812960* srpB (hex string):00857f70b197a6f3 f79c4270a41c581d62c7ec7fc554c797 481d4b4075b06be3df7f4f189e71fbec 08d1bcff8c5e4f7465256cba8a78b725 daa0b9bddcbbea43d916067b12c59aaf 4a9cdad53e08e4a5770ea72287987302 2c5f5f608eb94795710a907e1b425080 688d9e7790ce07816e6b2cdb9ad2c18f 60a2a5feb91b6da392579c5eb1e36f42 5b85c34085b216b97c4a3f7ffeb887c8 78ce0152d8be66eb9c7a51abbae3b3f6 56c6e56d95d3e148a23af3e9aaa54c72 cde19b58bdcbfb34b9eb7f6dcbcd86e2 7e6221f6d3da2517255088f5e7c408b3 7d6765120134b71986287225d781c49a e5436b89525e17ebdcb8f3b7eb43163a cfb31c45a51a5267 Later, getToken2() will be called with the client's srpA string and its M1 key-confirmation string. srpA is combined with srpB to calculate the "u" integer. srpA is also turned into an integer and used to compute the shared-secret "S" integer. S is then used to compute the shared key "srpK", which is the output of the SRP process. === SRP Client Calculation === While the client is waiting for the response to getToken1(), it begins its key-stretching calculations. Everything else must wait until the response to getToken1() arrives, which includes the key-stretching parameters (which are retroactively confirmed), srpSalt, and the server's generated srpB value. [[File:PICL-IdPAuth-SRP-Client1.png|client-side SRP 1]] Once the client knows srpSalt, it computes the same "x" integer as it did in the middle of the srpVerifier calculation. It also converts srpB into an integer named "B". Then it creates a random "a" integer, uses it to compute the string "srpA", then combines srpA with the server's srpB to compute the "u" integer. It then combines the static "k", the password-derived "x", the combined "u", and the server's "B", together with some magic math, to derive the "S" integer. If everything went well, the client will compute the same "S" value as the server did. If not (the password was wrong, or the client is talking to a fake server that doesn't really know srpVerifier), then the two "S" values will not match. * a (hex integer, normally random but pre-calculated for this example):00f2000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 000000000000115c* a (as decimal integer):119334647663227291363113405741243413916434827363146166012200067038894142816254113710841716638008805209543910927476491099816542561560345503311330152550056221240122563520612198703057065667637570340647063422988042473190059156975005813463818646696643573820202000369152615667401021816298491297653620614440782978764393137821956464627163145421579373439868081673415678986432326806001408975760610901250649711198896213496068605039486228645916762983047459546900860937537468108474188471985145427757080362211874088739962880012800917057512380049765406348391068882236386645531489818952050236879990719946264951520393624479315530076* srpA (hex string)00f2a357d7da7132 1be6c070fb3a59288cec951cb13e7645 1f8c466ab373626a7272dc1484c79ea3 cd1ea32e57fa46652e6450aa61ac5ee7 eac7a8c06c28ab195ccbe57500062c50 1a15fbb23a7f71b235448326af5e51c0 63f167378c78213793dbc54efb32f204 de753d7a6b3d826daaefc007d17862af 9b6a14e35f17f1eb8b13c7b8ffa1f6f4 7b70d62bd0c351b47596b0b0abcba95c 2d731869ed6e4ec24ab90da8cb22e65d 256315ee84d8079b4086d90c4e827b51 bb4e4d2d7b387da02e6b48904a3ba6d7 648a9bcdf3e9fc607cfba92f8eacae12 3ac45a79307cf3dd281ed75a96c7de8f cd823f148dcc06349795f825fb029859 b963ab88320133de* u (hex string)610c6df1f495e429 8a2a59a0f5b00d47ea2ed6ce2ccec8f7 ade158314a7bd794* S (hex string)009cc8da2f7a9501 5bc0091faa36d6efff52c33b924353e1 1de1d8e738654d6f6a481003acb17cae 2ba2d4ae3fea84314c940397640fce92 d9153dffb7f3bd29cbdb49e4ff0d26c4 67061337fd3708514e3039d24cb54dc4 6420426b0daf772463fe06eb1521c7b0 96c4eeb6e5f9f73949dcc74bc91baab8 398aff6df6735da2c9486a645a20f2d7 d8f455a2bd226f21e127f23e202b21fd d4ef64dc1a6740b6fcd2a6b032fcb393 a2b9d97506b6fb895585d29173cc0e89 c3b3077ffa31215db602b28364f81012 46ee9e8c47b63881f3f867e67971825d f6a881d1142989abcd4abba9c27ae529 c31be53f69966ccb81f7660f95d5f8fc 45d052df3bcbb761 [[File:PICL-IdPAuth-SRP-Client2.png|client-side SRP 2]] To safely tell if the "S" values match, both client and server combine srpA, srpB, and their (independently) generated "S" strings to form a string named "M1". The client sends M1 (along with srpA) in the getToken2() message. The server compares the client's copy of M1 against its own. If they match, the client knew the password and the server can safely respond with the encrypted account data. If they do not match, the client (or a man-in -the-middle attacker) did not know the password, and the client should increment a counter that can trigger defenses against online guessing attacks. Both client and server also hash "S" into "srpK". This is the shared session key, from which specific message encryption and MAC keys are derived (as described below). * M1 (hex string):182ff26523922c52559cab3cdfc89a74c986b1d7504ea53d11d9a204fc54449d* srpK (hex string):78a36d3e0df089e729a98dee3290fc4964cd6ec96b771d6abb6efe9181be868b  === SRP Notes === The SRP "g" (generator) and "N" (prime modulus) should use the 2048-bit value from RFC 5054 Appendix A. Clients should not accept arbitrary g/N values (to protect against small primes, non-primes, and non-generators). In the future we might allow alternate parameter sets, in which case the server's first response should indicate which parameter set to getToken1use.
The client does its entire SRP calculation in a single step, after receiving the server's "B" value. It creates its "A" value, computes the shared secret S, and the proof-of-knowledge M1. It sends both "A" and "M1" in the same message (getToken2).
The server receives "A"in getToken2, computes the shared secret "S", computes M1, checks that the client's M1 is correct, then derives the shared session key K. It then allocates a token (of the requested type) and encrypts kA+wrap(kB)+token as described below, returning the encrypted/MACed bundle in the response to getToken2. Outstanding crypto questions: * How exactly should the "a" and "b" integers be generated? The issue is of how much bias SRP can tolerate. Ideally these integers are uniformly distributed from 1 to N-1 (inclusive). The only way to obtain a purely uniform distribution from a source of random bytes is try-try-again: pick a (integral-number-of-bytes) number, compare it to the desired range, try again if it falls outside the range. If you get unlucky, this can take a lot of guesses, depending upon how close the range is to a power of two. ECDSA implementations tend to pick a number twice as long as the modulus and then modulo it down (rand(2^4096) % N), which yields a tiny fraction of a bit of bias. The cheaper approach is to do the same with a number of equal length (rand(2^2048) % N), which imposes more bias. Some SRP implementations appear to be satisfied by rand(2^256). We need more review here.* The original SRP papers defined M1=H(A+B+S) as we use here, but other implementation (in particular RFC2945) uses a curious construct that includes the username, the salt, and an odd XOR combination of N and g. We need to decide what to use for M1.
== getToken2 ==
Confirm
471
edits

Navigation menu