tag:blogger.com,1999:blog-372207522024-02-19T06:07:26.894+01:00ignisvulpisAnonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.comBlogger306125tag:blogger.com,1999:blog-37220752.post-18217264418299323012018-08-13T11:04:00.000+02:002018-08-13T11:04:48.732+02:00Starting the Hyperledger Indy test pool reachable on your WIFI network <div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJQUo8yFc7M5OscI1dBAW6C5lz1S50QP3hOF-qEUVv4R35FzUzajNNKTGoW05iCIHoYVg2P2q_SaBwaYrMFwGGlU3BuBERZl0oiMV2XMmwYUMfZeZ2p28SQixLTxSgy7ooMgp-zw/s1600/sovrin-identity-for-all.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="196" data-original-width="603" height="104" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJQUo8yFc7M5OscI1dBAW6C5lz1S50QP3hOF-qEUVv4R35FzUzajNNKTGoW05iCIHoYVg2P2q_SaBwaYrMFwGGlU3BuBERZl0oiMV2XMmwYUMfZeZ2p28SQixLTxSgy7ooMgp-zw/s320/sovrin-identity-for-all.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
<a href="https://github.com/hyperledger/indy-sdk">Hyperledger Indy</a>'s README.md explains how to start the <a href="https://sovrin.org/">@Sovrin</a> test pool on localhost using docker and in a docker network.<br />
<br />
<br />
Doing it this way the pool is not reachable from clients that are not on your local machine.<br />
Building a mobile app then has the problem that the phone can't talk to the test pool because neither localhost nor the private docker network are reachable.<br />
<br />
<h3>
Starting the test pool on a specific IP address</h3>
Dockerfile <code>ci/indy-pool.dockerfile</code> supports an optional pool_ip param that allows
changing the IP address of the pool nodes in the generated pool configuration.<br />
<br />
You can start the pool with e.g. the IP address of your development machine's WIFI interface
so that mobile apps in the same network can reach the pool.<br />
<br />
<blockquote class="tr_bq">
<pre><code># replace 192.168.179.90 with your wifi IP address
docker build --build-arg pool_ip=192.168.179.90 -f ci/indy-pool.dockerfile -t indy_pool .
docker run -itd -p 192.168.179.90:9701-9708:9701-9708 indy_pool</code></pre>
</blockquote>
<pre><code> </code></pre>
To connect to the pool the IP addresses in /var/lib/indy/sandbox/pool_transactions_genesis (in docker) and the
pool configuration you use in your mobile app must match.<br />
<br />
<a href="https://github.com/hyperledger/indy-sdk/blob/master/wrappers/java/src/test/java/org/hyperledger/indy/sdk/utils/PoolUtils.java#L41">Here</a> is some Java code that creates a pool configuration. Be sure to put your IP address in there when you open the pool connection.<br />
<br />
-------<br />
<br />
Please contribute to Indy. Even if your company does not allow you to publish code please consider helping by improving the documentation. <br />
<blockquote class="tr_bq">
Please sign-off your commits. git commit -s -m 'my first commit' README.md</blockquote>
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-89290397695833693532018-08-06T13:24:00.001+02:002018-08-07T16:31:38.721+02:00Building an Android App with Sovrin<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNIph9guQtqWWaKKrn_8_6yh9UGZriSkOJoWr2Rn20ZqkNHZxPzglerRDObKTJWwYDl14SypUp1k6k61mcYBZRQTx-OPCIU1i9YKPw3AYJYrjUdCcuDi6REIHFBlhyphenhyphen1_igh3Dbjw/s1600/hyperledger_indy_logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="473" data-original-width="1600" height="94" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNIph9guQtqWWaKKrn_8_6yh9UGZriSkOJoWr2Rn20ZqkNHZxPzglerRDObKTJWwYDl14SypUp1k6k61mcYBZRQTx-OPCIU1i9YKPw3AYJYrjUdCcuDi6REIHFBlhyphenhyphen1_igh3Dbjw/s320/hyperledger_indy_logo.png" width="320" /></a></div>
<br />
<br />
<br />
<br />
Thanks to the hard work of <a href="https://github.com/faisal00813">Mohammad Abdul Sami</a> <a href="https://sovrin.org/">Sovrin</a> enthusiasts now have support building libindy for Android in the <a href="https://github.com/hyperledger/indy-sdk/blob/master/doc/android-build.md">master</a> branch of our repo.<br />
<br />
<br />
You can now build the libindy libraries for Android by just running a script. Yeah!<br />
If you want to spare that building process you can download the libraries from <a href="https://repo.sovrin.org/android/libindy/stable/1.6.1/">Evernym</a>. Thanks!<br />
<br />
Now what? You have a libindy.so for arm, arm64 and x86, but how do you use it?<br />
<br />
I have created an Android Studio sample application <a href="https://github.com/AxelNennker/DroidLibIndy">DroidLibIndy</a> that you might use as a starting point (if you don't like reading blog posts).<br />
<br />
Still reading? Here is a list of quirks you need in your flashy new Indy-App.<br />
<br />
<ol>
<li>First you have to put the libindy library into the correct jni folder e.g.:<br /> app/src/main/jniLibs/arm64-v8a<br /><a href="https://developer.android.com/studio/projects/gradle-external-native-builds">This</a> other way to do this did not work for me.</li>
<li><a href="https://github.com/AxelNennker/DroidLibIndy/blob/master/app/build.gradle#L24">Source code and Target compatibility</a> have to be Java 1.8<br />Otherwise CompletableFuture and other stuff do not compile</li>
<li>You need a <a href="https://github.com/AxelNennker/DroidLibIndy/blob/master/app/src/main/AndroidManifest.xml#L8">network security policy</a> because libindy secures its communication using <a href="https://zeromq.org/">zeromq</a> and Android only accepts HTTPS as a secure protocol.</li>
<li>You might need a <a href="https://github.com/AxelNennker/DroidLibIndy/blob/master/app/lint.xml">lint.xml</a> to get <a href="https://github.com/java-native-access/jna">JNA</a> linked.</li>
<li>Copy libindy's <a href="https://github.com/hyperledger/indy-sdk/tree/master/wrappers/java/src/main/java/org/hyperledger/indy/sdk">Java wrapper code</a> to your project using the path org/hyperledger/indy/sdk. <br /><blockquote class="tr_bq">
cp -r ~pathto/indy-sdk/wrappers/java/src/main/java/org/ pathtoyourapp/app/src/main/java/</blockquote>
I did not try the maven route here.</li>
<li>In your app's onCreate method <a href="https://github.com/AxelNennker/DroidLibIndy/blob/master/app/src/main/java/indy/hyperledger/org/droidlibindy/DroidLibIndy.java#L39">set</a> the environment variable 'EXTERNAL_STORAGE'</li>
<li>Of course you need to have all the dependencies <a href="https://github.com/AxelNennker/DroidLibIndy/blob/master/app/build.gradle#L35">configured</a> in your build system.</li>
</ol>
As always: PRs are welcome! Please contribute to libindy. It's easy. <br />
<br />
Have fun exploring <a href="https://www.hyperledger.org/projects/hyperledger-indy">Hyperledger Indy</a> on Android!<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXdDI8z7ubjknqLQMnMZjZGeQFA_RJoJj42ORhM_-p_8F-Tw1aTEy9odvQGCwxk6ncMzgslkB3BgWgwZ1zO0TMby55pbDLD5kU66UzOjvcDi-UfacONYPWuYFCUIWtT47KI7YikA/s1600/Android-Sovrin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="343" data-original-width="280" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXdDI8z7ubjknqLQMnMZjZGeQFA_RJoJj42ORhM_-p_8F-Tw1aTEy9odvQGCwxk6ncMzgslkB3BgWgwZ1zO0TMby55pbDLD5kU66UzOjvcDi-UfacONYPWuYFCUIWtT47KI7YikA/s320/Android-Sovrin.png" width="261" /></a></div>
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-24750944023207632912018-04-25T13:07:00.000+02:002018-05-17T16:13:34.397+02:00Building openssl for libindy and Android<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNCt6OsdbQZLZrFZ6tU3QVpu8pzh3yJEwIqzI2Zy7oxWTXvKnTwL8DU1ihuyaEh3hxMjvClTAY-MNssx5cjiPw-D7jekDrBTuq5w_hr0kihHrzWOk2nxaHWlOa-XKR5LZLyaV72g/s1600/sovrin.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="240" data-original-width="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNCt6OsdbQZLZrFZ6tU3QVpu8pzh3yJEwIqzI2Zy7oxWTXvKnTwL8DU1ihuyaEh3hxMjvClTAY-MNssx5cjiPw-D7jekDrBTuq5w_hr0kihHrzWOk2nxaHWlOa-XKR5LZLyaV72g/s1600/sovrin.jpg" /></a></div>
Building of the <a href="https://github.com/hyperledger/indy-sdk" target="_blank">indy-sdk</a> for Android is currently not supported out of the box. The underlying issue is that libindy is implemented in Rust and the Android platform is currently not supported.<br />
<br />
To build openssl for Android on your Ubuntu system take the following steps:<br />
<ol>
<li>Setup your <a href="https://github.com/hyperledger/indy-sdk/blob/master/doc/ubuntu-build.md" target="_blank">build environment</a> - missing tools are likely to be noticed by "configure" so you can install them then </li>
<li>Download <a href="https://www.openssl.org/source/">openssl</a> (I used version 1.0.2n) and unpack it.</li>
<li>Setup the <a href="https://developer.android.com/studio/index.html">Android toolchain</a> (command line tools are enough) and <a href="https://developer.android.com/ndk/index.html">NDK toolchain</a> for e.g. arm<br /><blockquote class="tr_bq">
${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 14 --arch arm --install-dir ${NDK_TOOLCHAIN_DIR}/arm --stl=libc++</blockquote>
or for arm64<br />
<div style="margin-left: 40px;">
${NDK_HOME}/build/tools/make_standalone_toolchain.py --api 21 --arch arm64 --install-dir ${NDK_TOOLCHAIN_DIR}/arm64 --stl=libc++</div>
<div style="margin-left: 40px;">
</div>
</li>
<li>Edit the script <a href="https://wiki.openssl.org/index.php/File:Setenv-android.sh">setenv-android.sh</a><br /><br />I have these values:<br />_ANDROID_NDK="android-ndk-r16"<br />_ANDROID_EABI="arm-linux-androideabi-4.9"<br />_ANDROID_ARCH=arch-arm<br />_ANDROID_API="android-14"</li>
<li>Run the script '. setenv-android.sh'</li>
<li>run this:<br />./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine --openssldir=/usr/local/ssl/arm/$ANDROID_API --prefix=/usr/local/ssl/arm/$ANDROID_API</li>
<li>Edit Makefile and add <br />"--sysroot=/home/ignisvulpis/NDK_TOOLCHAIN_DIR/arm/sysroot/" <br />to CFLAG and DEPFLAG<br />Remove -mandroid where it occurs</li>
<li>Run make. This creates the libraries in the current directory<br />make build_libs</li>
<li>Make install fails because the application openssl is not build for Android.<br />So put a comment # in front of the install command.<br />"#@set -e; target=install; $(RECURSIVE_BUILD_CMD)" in the target "install_sw". "make install" now installs the include files and the libs.</li>
</ol>
The include files are needed to compile libindy. The libraries need to be put into a place where the Rust build system can find them. <br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-87342112908309793932017-10-15T17:58:00.001+02:002017-10-15T17:58:20.757+02:00Minimize Ladder Length over WallSome time ago somebody had to solve this math optimization question for their studies and told me about it.<br />
<br />
So there is a wall with height h, which has the distance a from a very high "building" and your task, should you accept it, is to find the shortest ladder over the wall that touches the ground and the "building".
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHaYOuWLxCDURnjjvNfPAgk3vLvvX9UkYRkh7qwDbOmixiACOWGd4SdsBUsM7k-QBfGcnPYRgYVnIQevjISFw9stqbW-BQ4rfET3euqBMGPZ_u10wqihaBZnx9Demo_yaZ4X2kjw/s1600/leiter.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img alt="" border="0" data-original-height="357" data-original-width="558" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHaYOuWLxCDURnjjvNfPAgk3vLvvX9UkYRkh7qwDbOmixiACOWGd4SdsBUsM7k-QBfGcnPYRgYVnIQevjISFw9stqbW-BQ4rfET3euqBMGPZ_u10wqihaBZnx9Demo_yaZ4X2kjw/s320/leiter.gif" title="Ladder over Wall" width="320" /></a><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
So the function to minimize is L = sqrt((x+a)^2+(h+y)^2).<br />
Because we know that y/a = h/x it follows that y = ah/x.<br />
<span style="font-family: inherit;"><span style="font-size: small;">Using this the length become L = sqrt((x+a)^2+(h+ah/x)^2)</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;">The minimum of that function is not changed if we leave out the sqrt and the derivation of (x+a)^2+(h+ah/x)^2 is (2 (a + x) (-a h^2 + x^3))/x^3</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;">So the minimum x is where this function equals zero, which is if x³ = ah²,</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;">and the length then is L = </span></span><span style="font-family: inherit;"><span style="font-size: small;">(a^(2/3) + h^(2/3))^3</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;"> </span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;">Now the thing that I find strange. Please look at this drawing (which is not really correct because the two "y" do not have the same length).</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;"><br /></span></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjptSnE37Tcva_nYjPXCK-dtYZZS6kmWPtH28H6-4V0RHp4FVo8nLjyGfXQqqQNPN2dK4_bg2uJAfF_KBROvaojjx6RID8Wr-rVkijgmpM5ImYlEvk9Zl-nYvIoLgG-B5ljzHpZGw/s1600/leiter.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="357" data-original-width="558" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjptSnE37Tcva_nYjPXCK-dtYZZS6kmWPtH28H6-4V0RHp4FVo8nLjyGfXQqqQNPN2dK4_bg2uJAfF_KBROvaojjx6RID8Wr-rVkijgmpM5ImYlEvk9Zl-nYvIoLgG-B5ljzHpZGw/s320/leiter.gif" width="320" /></a></div>
<br />
<span style="font-family: inherit;"><span style="font-size: small;"></span></span><br />
<br />
<br />
<span style="font-family: inherit;"><span style="font-size: small;">If the angle ACD is 90° then the ladder has minimal length!</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;">We know that ah=xy, so let's square that: a²h²=x²y² and because ACD is 90° xa=y² which yields</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: inherit;"><span style="font-size: small;">a²h²=x²xa and that gives x³=ah² which is exactly what we got by using the calculus.</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;"><br /></span></span>
<span style="font-family: inherit;"><span style="font-size: small;">Do you have a geometric explanation why L is minimal if ACD is 90°?</span></span><br />
<span style="font-family: inherit;"><span style="font-size: small;"><br /></span></span>
<br />
<span style="font-family: inherit;"><span style="font-size: small;"> </span></span><br />
<br />
<br />
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-64108319005831039872016-10-17T18:49:00.000+02:002016-10-17T18:49:05.384+02:00CSS Oddities: anonymous inline whitespace nodesI learned something today. All started with a <a href="https://twitter.com/supersole/status/787956777295945728" target="_blank">@Twitter post</a> by <a href="https://twitter.com/supersole" target="_blank">@supersole</a> that there is a new feature in <a href="https://nightly.mozilla.org/" target="_blank">@firefoxnighly</a> that now allows debugging "anonymous inline whitespace" nodes in HTML pages.<br />
<a href="https://blog.nightly.mozilla.org/2016/10/17/devtools-now-display-white-space-text-nodes-in-the-dom-inspector/">https://blog.nightly.mozilla.org/2016/10/17/devtools-now-display-white-space-text-nodes-in-the-dom-inspector/</a><br />
<br />
The post claims that imgimg on the page is rendered differently than <img />imgcrlfwhitespacecrlf<img />img.<br />
I could not believe this. That is stupid right? Which web developer would expect any difference?<br />
<br />
Well, it seems that CSS rules - being what they currently are - lead to this unexpected difference.<br />
The CSS spec describes the algorithm to process the HTML here in <span style="font-weight: normal;"><a href="https://www.w3.org/TR/css-text-3/#white-space-phase-1" target="_blank">Phase I: Collapsing and Transformation</a>.</span><br />
<span style="font-weight: normal;">In the second HTML fragment the whitespace is deleted by step 2 which gives us </span><br />
<img />imgcrlfcrlf<img />img.<br />
Step 2 tells us to handle segment breaks ("crlf"). That is described in the <span style="font-weight: normal;"><a href="https://www.w3.org/TR/css-text-3/#line-break-transform" target="_blank">Segment Break Transformation Rules</a>.</span><br />
<span style="font-weight: normal;">Those rule give us img</span>spacespaceimg<img />. Which is then again continued to be processed by the Phase I steps 3 and 4. Step 3 does nothing in this example.<br />
<br />
Step 4 reads:<br />
<blockquote class="tr_bq">
Any space immediately following another collapsible space—even one
outside the boundary of the inline containing that space, provided they
are both within the same inline formatting context—is collapsed to
have zero advance width. (It is invisible, but retains its <a href="https://www.w3.org/TR/css-text-3/#soft-wrap-opportunity"><i>soft wrap opportunity</i></a>, if
any.) </blockquote>
So the remaining two spaces are turned into one (or two - I don't care to check) empty text nodes with zero width but with "soft wrap".<br />
<br />
Good to know - maybe. Is this a feature? I expected that everything between two HTMLElements that matches (whitespace)* is completely removed and not inserted into the rendering tree.<br />
<br />
Maybe this should be discussed here?: <a href="https://github.com/w3c/csswg-drafts/issues">https://github.com/w3c/csswg-drafts/issues</a><br />
Not my cup of tea.<br />
<br />
Thanks to <a href="https://twitter.com/upsuper" target="_blank">@upsuper</a> who pointed me to the relevant specs. <br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-1067575044115405942016-10-10T13:56:00.000+02:002016-10-10T13:56:57.784+02:00Twitter Markup<a href="https://www.w3.org/Icons/WWW/w3c_home_nb.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://www.w3.org/Icons/WWW/w3c_home_nb.png" /></a><a href="https://dev.twitter.com/cards/overview" target="_blank">Twitter Cards</a> are around for some time now and I recently wondered how commonly used they are?<br />
<br />
There is a nice blog post on Blogger on <a href="http://www.bloggerhow.com/2012/07/implement-twitter-cards-blogger-blogspot.html/" target="_blank">how to integrate them</a> there but clearly there should be ways for e.g. <a href="view-source:http://www.spiegel.de/politik/ausland/donald-trump-vs-hillary-clinton-jetzt-folgen-vier-wochen-hoelle-a-1115885.html" target="_blank">newspapers </a>to promote their reports by providing summaries and a main image and author information that is not @Twitter specific? <a href="http://microformats.org/" target="_blank">Microformats</a> and schema.org to the rescue?<br />
<br />
What does Google do? It seems that <a href="https://developers.google.com/search/docs/guides/intro-structured-data" target="_blank">JSON-LD is the recommended format</a>.<br />
<br />
How would a Twitter Card look in JSON-LD?<br />
<br />
Twitter Cards or Rich Cards or @w3c Cards? <br />
<br />
Time to standardize!<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-86383626388688399192015-03-30T15:52:00.000+02:002015-03-30T15:52:00.820+02:00New Firefox Add-On: QRCode LoginCurrent login mechanisms suffer from missing support by browsers and sites.<br />
Browsers offer in-browser password storage but that's about that.<br />
Standardized authentication methods like <a href="https://www.ietf.org/rfc/rfc2617.txt" target="_blank">HTTP Digest Authentication and HTTP Basic Authentication</a> were never really accepted by commercially successful sites. They work but the user experience is bad especially if the user does not have an account yet.<br />
<br />
So most sites are left with form-based authentication were the site has full control over the UI and UX. Sadly the browser has little to offer here to help the site or the user other then trying to identify signup and login forms through crude guesses based on password field existence.<br />
<br />
There is no standardized way for sites and browsers to work together.<br />
Here is a list of attempts to solve some of the above issues:<br />
<ul>
<li><a href="http://ignisvulpis.blogspot.de/2011/03/all-those-nascars.html" target="_blank">All those NASCARs suggests navigator.openid</a></li>
<li><a href="https://www.mozilla.org/en-US/persona/" target="_blank">Mozilla's Persona / BrowserID</a> suggests navigator.id</li>
<li><a href="http://ac.openid.net/" target="_blank">The OpenID Foudation's AccountChosser</a> uses localstorage and redirects</li>
<li>The <a href="http://w3c.github.io/webappsec/specs/credentialmanagement/" target="_blank">W3C Credentialmanagement WG</a> uses navigator.credentials </li>
<li><a href="http://ignisvulpis.blogspot.de/2014/11/x-auto-login-at-google.html" target="_blank">Google's X-Auto-Login</a> utilizes HTTP headers</li>
<li><a href="https://developer.chrome.com/multidevice/requestautocomplete-faq" target="_blank">Google's requestAutocomplete</a> for Google Wallet is proprietary</li>
<li><a href="http://www.w3.org/wiki/WebID" target="_blank">WebID</a> uses URIs to identify entities</li>
<li><a href="http://www.inames.net/" target="_blank">XRI / inames </a>gives you more than =jane</li>
<li>...</li>
</ul>
Federations have their drawbacks too. Even Facebook login went dark for 4h a while ago which left sites depending on Facebook without user login.<br />
<br />
In general there is this chicken-egg problem:<br />
Why should sites support new-mechanism-foo when there is no browser support.<br />
Why should browsers support new-mechanism-foo when there are no sites using it.<br />
<br />
Then there are password stores. I use passwordsafe to store my password in one place. If I do not have access to that place (PC) then I can't login. Bummer.<br />
Others use stores hosted on the Internet and those usually support most browsers and OSses through plugin/addons and non standard trickery.<br />
I never could convince myself to trust the providers.<br />
<br />
So. Drum-roll.<br />
I started to work on a mechanism that has a password store on the mobile which allows you to login on your PC using your PC's camera.<br />
<br />
The user story is as follows:<br />
<ol>
<li>browse to a site's login page e.g. https://github.com/login</li>
<li>have my Firefox addon installed <br /><a href="https://github.com/AxelNennker/qrcodelogin">https://github.com/AxelNennker/qrcodelogin</a></li>
<li>click on the addon's icon</li>
<li>present your credential-qrcode to the PC's camera</li>
<li>be logged in</li>
</ol>
Here is an example qrcode containing the credentials as a JSON array<br />["axel@nennker.de","password"]:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoBPzd3gbCDwJRrNd9JRY5dAM_PD4Twqy-YdXu9NhzkN5n3HK_AfGCz8dRSUZ85nkgsP1ShxvK47TS8kViNjnrSPJlxWqLHtcva8ZuBpNS4ZQM0dshf9OtLXfG4Iw8xSUlmyiuGA/s1600/example-qrcode.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoBPzd3gbCDwJRrNd9JRY5dAM_PD4Twqy-YdXu9NhzkN5n3HK_AfGCz8dRSUZ85nkgsP1ShxvK47TS8kViNjnrSPJlxWqLHtcva8ZuBpNS4ZQM0dshf9OtLXfG4Iw8xSUlmyiuGA/s1600/example-qrcode.jpg" height="320" width="320" /></a></div>
<br />
<ol>
</ol>
The qrcode could be printed on paper or generated by your password store on your mobile. To help the user with the selection of the matching credentials the addon presents a request-qrcode to be read by the mobile first. This way the mobile ID-client can select the matching credentials. <br />
(If you don't like to install addons to test this and for a super quick demo of the qrcode reading using your webcam please to to <a href="http://axel.nennker.de/gum.html">http://axel.nennker.de/gum.html</a> and scan a code)<br />
<br />
What are the benefits?<br />
<ul>
<li>no need to change the site's javascript, html markup or https headers. No changes whatsoever needed on the accepting site.</li>
<li>no need to have an extra backend server to store your credentials.</li>
<li>no need to have an extra backend server to help mobile and browser to communicate.</li>
<li>no need for an enhanced browser or client. no need for the browser to know about new markup, new javascript APIs or HTTP headers.</li>
</ul>
What are the drawbacks?<br />
<ul>
<li>reading the qrcode from the mobile's screen very much depends on the light and camera. Printed credentials work reliably but qrcode on mobile screens sometime give me headaches.</li>
<li>You have to install the addon.</li>
<li>This is an alpha version. Your mileage may vary. </li>
</ul>
<br />
Screenshots:<br />
<br />
Login page at githup with addon installed:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3gQa1e0Q2KtBxgOyTgXTRKbToz2UFj2z1qcHUlNTaDU6bYQFcm5ebb3xvX0wKXdXgDk7-K38hl7eGmQesedZ_AY7rdQG4FdeEUhS4Auj5LHp6sdwliRMd02XxgBBe0e4hxRa8pg/s1600/github-login-with-addon-icon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3gQa1e0Q2KtBxgOyTgXTRKbToz2UFj2z1qcHUlNTaDU6bYQFcm5ebb3xvX0wKXdXgDk7-K38hl7eGmQesedZ_AY7rdQG4FdeEUhS4Auj5LHp6sdwliRMd02XxgBBe0e4hxRa8pg/s1600/github-login-with-addon-icon.png" height="177" width="320" /></a></div>
<br />
<br />
Screen after pressing the addon's toolbar icon. The qrcode helps the mobile ID-client to find the matching credentials:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhISUgC1p4bPWU80MYFOKLs1B4NAH_o0SwJJ4XiyIg_gxfluQQx7SP1ACnV2-ICxeNwAUYo1Ql3DehgBHggtnX7uBXSCM6qWWR6LAEIEHjzJsR3EhYvaqB81jAK2N5SqcwFr21P6g/s1600/qrcode-requirements-for-login.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhISUgC1p4bPWU80MYFOKLs1B4NAH_o0SwJJ4XiyIg_gxfluQQx7SP1ACnV2-ICxeNwAUYo1Ql3DehgBHggtnX7uBXSCM6qWWR6LAEIEHjzJsR3EhYvaqB81jAK2N5SqcwFr21P6g/s1600/qrcode-requirements-for-login.png" height="177" width="320" /></a></div>
Screen showing the camera picture which is scanned for qrcodes:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC9jIn-MDTHCdLzsBXcht1AFluSTsrMW7yKZFI0NqLaXDQCNidkdROScB3aFj0uWWCff5uJd9ghzZI9BPZZP2OIlcTlAPE7m2UnXEca9Hd_SjNXx_dHlvNV0Ad9O-Uyjs-0G69ag/s1600/camera-picture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC9jIn-MDTHCdLzsBXcht1AFluSTsrMW7yKZFI0NqLaXDQCNidkdROScB3aFj0uWWCff5uJd9ghzZI9BPZZP2OIlcTlAPE7m2UnXEca9Hd_SjNXx_dHlvNV0Ad9O-Uyjs-0G69ag/s1600/camera-picture.png" height="177" width="320" /></a></div>
This is clearly only a first step but I believe that it has potential to be a true user-centric solution that helps me and you to handle the password mess.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com1tag:blogger.com,1999:blog-37220752.post-25964180116726270542015-03-07T12:13:00.002+01:002015-03-07T12:13:53.560+01:00x-auto-login at Mozilla Services?As I described here<br />
<br />
<a href="http://ignisvulpis.blogspot.de/2014/11/x-auto-login-at-google.html">http://ignisvulpis.blogspot.de/2014/11/x-auto-login-at-google.html</a><br />
<br />
Google is using a proprietary HTTP header named x-auto-login to log you into Google services like GMail using your local Android account.<br />
This is cool.<br />
<br />
Browse to a Google website and be logged in without the need to remember the super secure password.
Sadly this is a closed system as we learned when implementing this for Firefox for Android (Fennec).<br />
See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1030650">https://bugzilla.mozilla.org/show_bug.cgi?id=1030650</a><br />
<br />
Yes, Fennec can talk to the Authenticator and ask for a "weblogin:" token for "com.google" but the Authenticator answers differently depending on who asks.
If Chrome is asking then the returned token redirects you to https://accounts.google.com/ and immediately logs you in, but when you'r Fennec then you are just redirected to https://accounts.google.com/ and have to enter username and password. Bummer.<br />
<br />
Anyway: How about using this scheme for Mozilla services and using a Mozilla account on the device or local to the browser (Firefox Sync) if available.<br />
<br />
<ol>
<li>browse to e.g. <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1030650">https://bugzilla.mozilla.org/show_bug.cgi?id=1030650</a> (obviously a Mozilla service) and press the login button </li>
<li>get redirected to
https://accounts.firefox.com/ServiceLogin?service=bugzilla&passive=true&rm=false&continue=https://bugzilla.mozilla.org/show_bug.cgi?id=1030650
&ss=1&scc=1&ltmpl=bugzilla&emr=1 </li>
<li>the response includes an x-auto-login HTTP header in the response </li>
<li>Firefox sees the x-auto-login header and<br />- on desktop look for Firefox Sync account
use it to obtain a token from a token endpoint hosted at mozilla.org<br />- on Android ask the AccountManager for a weblogin token for "org.mozilla". </li>
<li>redirect to the token (the token is an URL). In this case e.g. https://accounts.firefox.com/?t=accesstokenb64&...</li>
<li>https://accounts.firefox.com/ validates the token and redirects back to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1030650">https://bugzilla.mozilla.org/show_bug.cgi?id=1030650</a> </li>
</ol>
I think this is doable and would benefit the users of Mozilla services.<br />
<br />
Next step then (there is always a next step) is to allow third party logins e.g. from githup to bugzilla using x-auto-login.<br />
<br />
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-4392736513195056112014-11-03T13:57:00.000+01:002014-11-03T13:57:37.475+01:00X-Auto-Login at GoogleBelow you can find evidence that Google is using the X-Auto-Login header in production.<br />
Please see my other post for context:
<a href="http://ignisvulpis.blogspot.de/2014/09/deviceautologin.html">http://ignisvulpis.blogspot.de/2014/09/deviceautologin.html</a><br />
I am using "wget" to get gmail web page and the HTTP response contains the X-Auto-Login header.<br />
<br />
I think that Google should standardize this.<br />
Currently Google is using OpenID2 here but it is probably ease to standardize this with <a href="http://openid.net/connect/">OpenID Connect</a>.
<br />
<br />
<pre>ignisvulpis@namenlos:~/mozilla-central$ wget -S https://mail.google.com/mail --user-agent="Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36"
--2014-11-03 12:23:50-- https://mail.google.com/mail
Connecting to 212.201.109.5:8080... connected.
Proxy request sent, awaiting response...
HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Fri, 01 Jan 1990 00:00:00 GMT
Date: Mon, 03 Nov 2014 11:23:51 GMT
Location: https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=googlemail&emr=1
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic,p=0.01
Connection: close
Location: https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=googlemail&emr=1 [following]
--2014-11-03 12:23:51-- https://accounts.google.com/ServiceLogin?service=mail&passive=true&rm=false&continue=https://mail.google.com/mail/&ss=1&scc=1&ltmpl=googlemail&emr=1
Connecting to 212.201.109.5:8080... connected.
Proxy request sent, awaiting response...
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Strict-Transport-Security: max-age=10893354; includeSubDomains
Set-Cookie: GAPS=1:lAGQAL021CeF4UofSLjbzRnvJw_Eqw:256mW0v3ZoeLVjLo;Path=/;Expires=Wed, 02-Nov-2016 11:23:51 GMT;Secure;HttpOnly;Priority=HIGH
Set-Cookie: GALX=xATUIfBPIN4;Path=/;Secure
X-Frame-Options: DENY
Cache-control: no-cache, no-store
Pragma: no-cache
Expires: Mon, 01-Jan-1990 00:00:00 GMT
</pre>
<b><smaller>X-Auto-Login: realm=com.google&args=service%3Dmail%26continue%3Dhttps%253A%252F%252Fmail.google.com%252Fmail%252F</smaller></b>
<br />
<pre> Transfer-Encoding: chunked
Date: Mon, 03 Nov 2014 11:23:51 GMT
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Server: GSE
Alternate-Protocol: 443:quic,p=0.01
Connection: close
Length: unspecified [text/html]
2014-11-03 12:23:51 (1,44 MB/s) - ‘mail’ saved [70172]
ignisvulpis@namenlos:~/mozilla-central$ </pre>
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-59701639181093960792014-09-12T14:04:00.000+02:002014-09-12T14:04:21.168+02:00DeviceAutoLoginMaybe you are an Android user and wondered how sometimes the browser logs you in without asking for a password?<br />
<br />
Well, I wondered but never found the time to investigate.<br />
<br />
Thanks to the awesome <a href="https://www.w3.org/2012/webcrypto/webcrypto-next-workshop/Overview.html">W3C Web Cryptography Next Steps Workshop</a> and thanks to the usual jet-lag I found that time now.
First I thought that this is Google-ism "Chrome does some questionable proprietary trick and knows just how to login to Google accounts". That is half-true.<br />
<br />
There is chatter on the chromium list but I seems that the Android browser knows this trick since 2011 and <a href="https://en.wikipedia.org/wiki/Google_Chrome_for_Android">Chrome for Android</a> was released in 2012.<br />
<br />
So how does it work?<br />
<ol>
<li>a site responds with a special HTTP header "X-Auto-Login" </li>
<li>the browser sees that header </li>
<li>the browser <a href="https://github.com/android/platform_packages_apps_browser/blob/master/src/com/android/browser/DeviceAccountLogin.java#L60">asks the device's account system for local accounts</a> for the realm parameter of the header (e.g. realm=com.google) </li>
<li>the browser asks for a special kind of token from that account </li>
<li>the browser asks the user for consent to login </li>
<li>the token is an URL - so if the user consents the browser opens that URL </li>
<li>the site the URL points to accepts the token </li>
<li>the site redirects the browser to the original page the user wants to use
</li>
</ol>
<br />
Tadah!<br />
<br />
I think this is neat. But why doesn't Google talk about it? Why isn't this standardized at W3C?<br />
Anyway. How can you benefit?<br />
As a user? You already do.<br />
As a website with your own mobile app?<br />
<ol>
<li>Well, Google is probably not issuing tokens for your site. Maybe they do or would do because they want to be an identity provider?... </li>
<li>Issue the tokens yourself.</li>
</ol>
<ol type="a">
<li> What you need on the Android device is an <a href="https://developer.android.com/training/sync-adapters/creating-authenticator.html">AccountAuthenticator</a>.
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL0-4YH8llOqxXMNdkZfc7EO8eWbQn79b7JeZqjQKk0IY6tzUGN7fUkcLm8M6Q5V5ZRQCWPLHt3IJmOciRXyo3Zslfnknql5OturTtvF9i2gZVl7giYNS89oPAYxLZzJrPte9kig/s1600/Screenshot_2014-09-12-04-11-57.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL0-4YH8llOqxXMNdkZfc7EO8eWbQn79b7JeZqjQKk0IY6tzUGN7fUkcLm8M6Q5V5ZRQCWPLHt3IJmOciRXyo3Zslfnknql5OturTtvF9i2gZVl7giYNS89oPAYxLZzJrPte9kig/s320/Screenshot_2014-09-12-04-11-57.png" /></a> </li>
<li>let your website issue the X-Auto-Login HTTP header "realm=com.yourdomain&args=..." </li>
<li>let your Account Authenticator from step a generate tokens based on 'String authTokenType="weblogin:" + args;' </li>
<li>let your site accept the tokens generated by your <a href="https://developer.android.com/reference/android/accounts/AbstractAccountAuthenticator.html">Account Authenticator</a>. </li>
</ol>
<br />
I think this is a good idea. If your company has an mobile app then build that Account Authenticator. This is even more true if your company has several mobile apps. (Put the authenticator in your own CompanyServices.apk (like Google does with the GooglePlayServices) so you can update independently from your apps.)<br />
<br />
You might know that I work for a 100% subsidiary of Deutsche Telekom. Why isn't DT doing this? Don't ask me. I am telling them for years that our own AccountAuthenticator would be "gold". But who listens to me. Working for a big company has its challenges.<br />
<br />
<p>Back to wondering... How can we get this or something similar standardized through W3C?</p>
<p>Maybe I should write a blog post to make it more known. But then who reads this blog anyway. ;-)</p>
<br />
Thanks for listening.
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-22164551510242354352014-02-18T10:05:00.000+01:002014-02-18T11:31:20.143+01:00Web Identity Restart?Well, how can you restart something that never started? ... Never mind.
<br/><br/>
I am wondering whether it makes sense to have a W3C workshop on "Internet Identity" again.
<a href="http://www.w3.org/2011/identity-ws/">http://www.w3.org/2011/identity-ws/</a>
<br/><br/>
My impression in 2011 was that the common ground was not very broad so the group decided to launch the <a href="http://www.w3.org/2012/webcrypto/">W3C WebCrypto</a> working group because all agreed that crypto is a precondition to web identity.
Now, three years later I do not see much progress in web crypto or web identity (for that matter).
<br/><br/>
In the meantime the <a href="http://fidoalliance.org/">FIDO alliance</a> was established which has HW-based authentication but a license model that requires that implementers are a FIDO alliance member. That is the opposite of a web standard.
<br/><br/>
So I think that the WebCrypto WG will not give us "identity for the web". Signing/verification/encryption/decryption are too low level and too easy to use wrong. This is not the way to web identity.
<br/><br/>
Maybe it is time to restart the web identity effort in W3C.Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-76010598558988714442013-07-09T17:54:00.001+02:002013-07-09T17:54:36.495+02:00ACM Digital Identity ManagementThe call for papers to ACM Digital Identity Management is open <a href="http://cccs.ncl.ac.uk/dim2013/">http://cccs.ncl.ac.uk/dim2013/</a><br />
<br />
<blockquote class="tr_bq">
<h2>
"Identity at the Crossroads"</h2>
This workshop will explore crucial issues concerning interoperable identity management technologies for the information society.
<br />
Identity management has seen a series of development in the recent
years. Whereas identity management and federation standards have been
solidified and adopted in practice, nations world-wide are investing in
electronic identity systems as strong root identities for their citizens
offering a promise for strong authentication. Privacy-enhancing
identity systems have reached some technical maturity and may offer user
authentication with minimal disclosure. At the same time, personal
identifiable information and the user's identity has become a commodity
to drive the business of global corporations. Whereas such companies
sought to bind the users accounts to their unique identity, there has
been a reported unrest and anxiety of users because of their diminishing
privacy protection.
<br />
We see identity at the crossroads. One possibility is the unique
identification and strong authentication road that may offer increased
trust for e-commerce and increasing cloud services. Another is the road
of attribute exchange and leveraging the user's personal identifiable
information that may benefit business and help users to have a
consistent experience among many mobile compute platforms. Finally,
there is the privacy-enhancing identity systems road that may offer
additional protection for the user's civil rights. Partially these
different roads seem to contradict each other. Research can offer roads
less taken that overcome these seeming contradictions and come up with
next generation identity solutions.
</blockquote>
<br />
See you in Berlin in November! Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-28232470001180742112013-06-10T12:20:00.003+02:002013-06-10T12:20:49.195+02:00HTTPS EveryWhere Kantara InitiativeI noticed that when I am logged into <a href="https://idp.kantarainitiative.org/">https://idp.kantarainitiative.org/</a> and I then access documents<br />
on kantarainitiative.org there is no SSL protection. This is probably not good.<br />
<br />
<a href="https://www.eff.org/https-everywhere" target="_blank">HTTPS Everywhere</a> to the rescue! <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVl-bBqlysrm9Cx1eUQ1P2W2I0fT0_tyOoGcjkZl1wxpq-QiQlg7Fo-rNaW0GfzO8StGLlZDaR4iULxbKrpS0nu7alSvDKnnCMdy5eG6CZFiXmRXdKodVXjDAR84VqeFOO3WE2Rw/s1600/HTTPS_Everywhere_new_logo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img alt="HTTPS Everywhere Logo" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVl-bBqlysrm9Cx1eUQ1P2W2I0fT0_tyOoGcjkZl1wxpq-QiQlg7Fo-rNaW0GfzO8StGLlZDaR4iULxbKrpS0nu7alSvDKnnCMdy5eG6CZFiXmRXdKodVXjDAR84VqeFOO3WE2Rw/s1600/HTTPS_Everywhere_new_logo.jpg" title="HTTPS Everywhere Logo" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
I added my own rule to the <a href="https://www.eff.org/files/https-everywhere-latest.xpi" target="_blank">HTTPS Everywhere Firefox addon</a>. (Works in Firefox 21.0)<br />
<blockquote class="tr_bq">
<br />
<ruleset name="KantaraInitiative"><br />
<target host="www.kantarainitiative.org" /><br />
<target host="kantarainitiative.org" /><br />
<target host="idp.kantarainitiative.org" /><br />
<br />
<rule from="^http://idp\.kantarainitiative\.org/" to="https://idp.kantarainitiative.org/"/><br />
<rule from="^http://(www\.)?kantarainitiative\.org/" to="https://kantarainitiative.org/"/><br />
</ruleset></blockquote>
<br />
Put the above <a href="https://www.eff.org/https-everywhere/rulesets" target="_blank">ruleset</a> into the Firefox Profile folder into a file named e.g. kantarainitiative.xml.<br />
On Windows it should be located in a folder similar to this location:<br />
<blockquote class="tr_bq">
D:\Users\nennker.axel\AppData\Roaming\Mozilla\Firefox\Profiles\uzmmhdde.default\HTTPSEverywhereUserRules</blockquote>
Now whenever I visit Kantara HTTPSEverywhere redirects Firefox to the SSL protected service.<br />
<br />
<a href="https://supporters.eff.org/donate" target="_blank">Support EFF!</a><br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-5221182113240046992013-05-30T10:03:00.000+02:002013-05-30T18:11:13.245+02:00Android SSOThe documentation of Android's <a href="https://developer.android.com/reference/android/accounts/AccountManager.html" target="_blank">AccountManager</a> is infamously uninformative. AccountManager is available since API level 5 and I got the impression that Google changed it a lot. I am not sure whether it is still work-in-progress. Probably.<br />
<br />
So how does Google do SSO for their own services? Not long ago Google introduced <a href="https://developer.android.com/google/play-services/index.html" target="_blank">Google Play Services</a> <br />
<br />
Google Play Services contains an <a href="https://developer.android.com/reference/android/accounts/AbstractAccountAuthenticator.html" target="_blank">Authenticator</a> that handles all Accounts for "com.google". The Google apps like GMail etc query this Authenticator for access tokens using the Authenticators getAuthToken method. The application can then use this access token to access the API of its backend server.<br />
<br />
How can this be secure? How does the Google Play Services SDK (GoogleAuthUtil) know that GMail is a trusted app?<br />
I am guessing here but I think that Google uses the same mechanism that Google recommends for developers. The keys used to sign an Android app are retrievable by the SDK and can be send to the backend. The backend then checks whether the keys match preconfigures keys.<br />
Of course this security has its limits. On a rooted phone or a custom build phone any app can claim to be the e.g. GMail app by replacing the Android library calls that fetch the signing keys. But then Google knows to which user (Google account) a phone is registered to. Maybe this can be used to inform the user that something is going on or the account can be inactivated. Difficult.<br />
(The new <a href="http://android-developers.blogspot.de/2013/03/now-is-time-to-switch-to-new-google.html" target="_blank">Google Play Developer Console</a> helps.)<br />
<br />
I think this level of security is acceptable for most consumer cases.<br />
<br />
So let's say your company is a mobile games company (Acme Games) and you want SSO between your apps. Now write your <a href="https://developer.android.com/training/id-auth/custom_auth.html" target="_blank">own authenticator</a> and put it into an apk e.g. "Acme Services".<br />
Now each of your games can query the existence of the Authenticator for your domain "com.acme".<br />
If it exists then ask for an access token. If it does not exist then the user has to prove to your backend that he knows something only he can know. (Successful login to a third party (e.g. <a href="http://android-developers.blogspot.de/2013/02/google-sign-in-now-part-of-google-play.html" target="_blank">Google+ Sign-In</a>) or plain username and password). In this step you should recommend to install Acme Services because it helps the user to login to future games he will install. (And synchronization services, backup etc).<br />
<br />
It is a pity that not each game can contain an Authenticator. In fact it can but I have not tried it out. I do not know what happens if there are several Authenticators claiming to be authoritative for "acme.com". I guess this leads to trouble or else Google would chosen this way for their own apps.<br />
At least it takes up space in each of your app... That is the official reason given by Google:<br />
<br />
<blockquote class="tr_bq">
<i>You're done! The system now recognizes your account type, right alongside all
the big name account types like "Google" and "Corporate." You can use the
<b>Accounts & Sync</b> Settings page to add an account, and apps that ask for
accounts of your custom type will be able to enumerate and authenticate just as
they would with any other account type.</i><br />
<i>Of course, all of this assumes that your account service is actually
installed on the device. If only one app will ever access the service, then
this isn't a big deal—just bundle the service in the app.
But if you want your account service to be used by more than one app, things get
trickier. You don't want to bundle the service with all of your apps and have
multiple copies of it taking up space on your user's device.</i><br />
<i><b>One solution is to place the service in one small, special-purpose APK</b>. When
an app wishes to use your custom account type, it can check the device to see if
your custom account service is available. If not, it can direct the user to
Google Play to download the service. This may seem like a great deal of
trouble at first, but compared with the alternative of re-entering credentials
for every app that uses your custom account, it's refreshingly easy.</i></blockquote>
<br />
<br />
It is a pity that GoogleAuthUtils are not configurable with your domain, your token endpoint etc. Maybe that is asking too much. We are on our own here and have to reimplements <strike>Google</strike>AuthUtils for our purposes.<br />
<br />
Through the method described in this post you are creating your own identity silo. Which is OK if your company is big enough and you do not care about the access tokens being useful at other (your business partners) sites. If you implement your own authenticator then the backend API and token format are all your own responsibility. PROTIP: use <a href="https://openid.net/connect/" target="_blank">OpenID Connect</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr1TRTU4jIrXtT1THvNwlCp1Hw7AxlvJHa8qSbUJKNMn53_Ao9DYH2mT-r78x839ldZEv4bpDBdcAKpPSugxqxBvCgseq0dEkv-ISgEks0xk-gyruxghX3JQB151XwMYo_ZHD3Ag/s1600/OpenID-Connect.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr1TRTU4jIrXtT1THvNwlCp1Hw7AxlvJHa8qSbUJKNMn53_Ao9DYH2mT-r78x839ldZEv4bpDBdcAKpPSugxqxBvCgseq0dEkv-ISgEks0xk-gyruxghX3JQB151XwMYo_ZHD3Ag/s1600/OpenID-Connect.jpg" /></a></div>
<br />
OpenID Connect is a profile of <a href="https://developers.google.com/accounts/docs/OAuth2Login" target="_blank">OAuth2</a>. Google is recommending it too. Use it!<br />
<br />
If you want interoperability later (business partner integration) then being standard compliant make things A LOT easier!<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-84436465639375067562013-05-28T14:14:00.000+02:002013-05-28T14:24:31.883+02:00Google: Standardizing Payments on the Web: Introducing requestAutocomplete()Google is taking huge steps to simplify payments. Which is great!<br />
<br />
If you have about 25 minutes then watch this presentation.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/1M50AXPd0Tg?feature=player_detailpage" width="640"></iframe>
The major takeaways:<br />
<ul>
<li>Sites should use standardized names for form input field's autocomplete attributes.<br /><input id="nme" name="username" autocomplete="full-name"><br />id and name stay as they are but site owner should use standard values for autocomplete.<br /><a href="http://wiki.whatwg.org/wiki/RequestAutocomplete" target="_blank">WhatWG</a></li>
<li>The browser presents the user with a dialog that allows to choose between different sets of data; e.g. change to different shipping address. </li>
<li>On Chrome there is tight integration with Google Wallet and instead of your real credit card information a one time credit card is issued by the Google Wallet backend.<br />Caveat: Google Wallet currently is US only!</li>
</ul>
<br />
Google Wallet is only one data source for autocomplete. If Google Wallet is not available then Chrome's local autofill data is used for autocomplete.<br />
<br />
Google said that they <a href="https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/blink-dev/0TnqLOvC2ZY" target="_blank">talked</a> to other browser vendors but that they
could not talks about it right now... Mozilla's <a href="https://mozillalabs.com/en-US/profile/0TtvVic-qdwWv838E89ekxSHivs/" target="_blank">Ben Adida</a> compares it to the geoLocation API. Although there is not official statement from Mozilla. Apple shows no reaction yet.<br />
<br />
<br />
Here is a screenshot from the presentation showing sample HTML markup.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMM535QpyVuguyu7zqjsWyc1arjUtcZLjPGf3sXWG77j_6GPx0tXhqhapg0OQnhaP4UZkipO2yoRcQqXr4vvy6haf-VenxHIzkohD6_kSaqisZK_pDS8RDef0d5OB7mnf7gNnMTQ/s1600/ChromiumAutocompleteMarkup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="203" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMM535QpyVuguyu7zqjsWyc1arjUtcZLjPGf3sXWG77j_6GPx0tXhqhapg0OQnhaP4UZkipO2yoRcQqXr4vvy6haf-VenxHIzkohD6_kSaqisZK_pDS8RDef0d5OB7mnf7gNnMTQ/s1600/ChromiumAutocompleteMarkup.png" width="320" /></a></div>
<br />
The documentation is <a href="http://www.chromium.org/developers/using-requestautocomplete" target="_blank">here</a>.<br />
<br />
Well, this reminds me of our <a href="http://informationcard.net/" target="_blank">information card</a> efforts.<br />
<br />
Microsoft - the inventor of information cards - took another approach then to integrate into the website. HTML5 was not really there in 2005. Microsoft <a href="http://docs.oasis-open.org/imi/identity/v1.0/identity.html" target="_blank">suggested</a> to use HTML object tags and the website could use the object's parameters to specify what attribute is needed. The Information Card foundation standardized the <a href="http://informationcard.net/resources/claim-catalog" target="_blank">attribute names</a>.<br />
We did some things differently than Google is doing now and maybe Information Cards where too secure and required too much change on the website. The most important difference between requestAutocomplete and the integration with Information Cards is that the data delivered to the site was a signed SAML token which could contain many more attributes about the user instead of only payment detail.<br />
Providing signed data is kind of a good thing because the site - the relying party - could immediately validate the signature and be sure that the attribute values are issued by a probably trusted issuer. (I won't go into self-issued cards here)<br />
Anyway, it seems the changes needed to be made to the site seemed to have been too big.<br />
<br />
Google's requestAutocomplete takes a smaller step. The user experience is probably similar if you compared requestAutocomplete and the information card selection. requestAutocomplete is a big step forward for the current web if it succeeds.<br />
The security improvements are not so big compared to information cards. The one time credit card feature is bound to Google Wallet and other browser vendors might not support Google Wallet. But this is probably not a show stopper. The security level of many current online payment schemes is in fact near zero. And requestAutocomplete is not going to change that.<br />
<br />
One thing that I would like to build. Support for requestAutocomplete through a wallet installed on the mobile phone.<br />
<br />
So Google's step forward is not as ambitious as the Information Card's one. But...<br />
Who cares if the overall completion rate sky rockets.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com1tag:blogger.com,1999:blog-37220752.post-24753440401863223792013-05-27T00:01:00.001+02:002013-05-27T17:22:34.090+02:00Google Wallet ObjectsDuring <a href="https://developers.google.com/events/io/" target="_blank">Google I/O</a> there were several presentations about <a href="https://www.youtube.com/watch?v=LwE_3aRapvc" target="_blank">Google Wallet Objects</a>.<br />
<br />
Although the documentation is not public one can get a few ideas what those objects are.<br />
<br />
What I find interesting is that we at <a href="http://www.laboratories.telekom.com/public/english/innovation/success-stories/pages/mobile-wallet.aspx" target="_blank">T-Labs</a> named the "things" inside our <a href="http://www.laboratories.telekom.com/public/english/innovation/exponate/pages/future-wallet.aspx" target="_blank">wallet</a> "objects" too.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg16ipu8pTro_oLWnKYKQyZJtMrTdVFaimS3oBKAUgTQBbEgEUXPlf45DtGca23B7Rhp17PwwFK_A7qySdY0UunFpo-1QWJfeoTGNzcEMlkMzqwGJTN1wX58BddQOwVaInF-NLrnw/s1600/future_wallet_screens_600.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg16ipu8pTro_oLWnKYKQyZJtMrTdVFaimS3oBKAUgTQBbEgEUXPlf45DtGca23B7Rhp17PwwFK_A7qySdY0UunFpo-1QWJfeoTGNzcEMlkMzqwGJTN1wX58BddQOwVaInF-NLrnw/s1600/future_wallet_screens_600.png" width="320" /></a></div>
<br />
Well, at first we just called them "cards" and the wallet is a card selector. The cards can be anything: payment cards, train tickets, loyalty cards, car keys, coupons. Everything that is in your wallet.<br />
<br />
Others called the "things" in the wallet "service". Some defined them just to be links to app on the same device as the wallet. Some defined them as meta data, that describes the service, the issuer, the service endpoints, the protocols needed to get tokens from the endpoints and so forth. Some objects contain code that is executed by the wallet.<br />
<br />
Our T-Labs wallet objects are currently called "items" and they are <b>all of the above</b>.<br />
They represent all the items in your wallet. It does not matter whether we call them items or objects.<br />
It does not matter (much) what the import format is: XML or JSON? Currently we are using an extended <a href="http://docs.oasis-open.org/imi/identity/v1.0/identity.html" target="_blank">OASIS IMI</a> format. In the extensions you can specify things like "app" for a wallet external application that provides extra functions of an item. Or you can specify "AID" to tell the wallet which cardlet on the SIM the item uses/needs. <br />
<br />
What is important in Google's presentations is the ecosystem they are building around the wallet. <a href="http://urbanairship.com/blog/2013/05/15/urban-airship-demonstrates-integration-of-alaska-airlines-loyalty-program-in-google" target="_blank">Urban Airship</a><span style="font-size: 1em; line-height: 1.5;">, a Google Wallet Sandbox partner,</span> has build a tool that makes it easy for wallet partners to create "objects". This is exactly what T-Labs demoed at the <a href="http://www.laboratories.telekom.com/public/Deutsch/Innovation/CeBIT_2012/Pages/mWallet.aspx">Cebit 2012</a> computer fair.<br />
It has to be easy for partners to build the wallet objects/items. Most partners should not have to care about the wallet object's format. It has to be easy to create and to deploy items to the wallet.<br />
<br />
I believe that the formats and protocols in the wallet ecosystem have to be open.<br />
I believe that the users should control the wallet objects: what item is in the wallet.<br />
<br />
Though I disagree with some of Google's decisions.<br />
<ul>
<li>Why keep the format and protocols kind of secret? </li>
</ul>
<ul>
<li>Why the restrictions? I find it laughable to try to ban "<a href="https://support.google.com/payments/answer/3139386">abortion</a>". Well, maybe it is not funny.It is the user's wallet. If they want a service then the wallet should not prevent it.<br />Google controls the wallet. It is Google's wallet. It is not the user's wallet. #fail</li>
</ul>
<ul>
<li>Why not the slightest hint to support online identity? Why not use e.g. your loyalty card or your club card to login into your favorite <a href="http://www.telekom.com/medien/produkte-fuer-privatkunden/168610">soccer</a> club's fan site and online shop?</li>
</ul>
Building the whole ecosystem at once is the right way. Calling the items "objects" is a nice coincident to my work.<br />
Interesting times...<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-41519408470849035552013-05-24T22:06:00.001+02:002013-05-24T22:06:56.622+02:00ALERT - DIAPER DANGEROUSLY FULL<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
Oh no! I should never have agreed to that <a href="http://connectid.blogspot.de/2013/05/identity-internet-of-things.html" target="_blank">IoT WebSSO thing</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeQ1p-PeQCdb7rxn7vk-R_H5_BZbBQRo_QvWEZu9UJzNU6vr2Rwz69kAIT2TzPurR_JOo18ccc1QxOzcSzPP_0DMlP6Fn-xUOiyXrh73u4cxduc3O_I8RCI2SEv5m06tgTWDO3_g/s1600/20130524_214711.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeQ1p-PeQCdb7rxn7vk-R_H5_BZbBQRo_QvWEZu9UJzNU6vr2Rwz69kAIT2TzPurR_JOo18ccc1QxOzcSzPP_0DMlP6Fn-xUOiyXrh73u4cxduc3O_I8RCI2SEv5m06tgTWDO3_g/s1600/20130524_214711.jpg" width="240" /></a></div>
<br /><div class="separator">
Every time I revoke that diaper token I am immediately signed back in by the craddle.
</div>
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-44879762717215113842013-05-17T11:34:00.000+02:002013-05-17T11:34:57.553+02:00FIDO AllianceI am not happy with the FIDO Alliance and their <a href="http://www.fidoalliance.org/faqs.html" target="_blank">FAQ </a>do not eliminate my concerns.<br />
<br />
The major concern beeing: "Why isn't this going straight to a standards body?"<br />
Their answer:<br />
<blockquote class="tr_bq">
<h5>
The FIDO authentication protocol needs to be part of a standardized,
interoperable ecosystem to be successful. Building this ecosystem
requires the active commitment of everybody from hardware chipset
vendors, to the manufacturers of back-end server systems. Coordination
across the divergent interests of these players is a complex affair, and
one that current technical standards bodies are not well suited to
handle.</h5>
<h5>
The FIDO Alliance will refine the protocol, and monitor the
extensions required to meet market needs and to make the protocol robust
and mature. Implementation will not be undertaken by the FIDO
Alliance. The mature protocol will be presented to the IETF, W3C or
similar body after which it will be open to all industry players to
implement.</h5>
</blockquote>
This is what standardization bodies working groups are for. Work on protocols and formats. Work on security considerations. Use the experience of "the community".<br />
<br />
So FIDO is developing a protocol and will then present it to one standardization body...<br />
Meanwhile it is a closed thing and it costs relevant amounts of <a href="http://www.fidoalliance.org/join.html" target="_blank">money </a>to join the alliance.<br />
This neither free nor open.<br />
<br />
During IIW there were several sessions on FIDO (<a href="http://iiw.idcommons.net/Strong_2-Factor_For_All_%E2%80%93_Google_and_FIDO_Alliance" target="_blank">1</a>, <a href="http://iiw.idcommons.net/FIDO_Alliance_%E2%80%93_Fast_Identity_Online_Overview/Nutshell" target="_blank">2</a>). Each full of good intentions and marketing speek but no substance. No real information. You have to join the alliance to get that. Well, ...<br />
<br />
Somebody at <a href="https://www.noknok.com/" target="_blank">Nok Nok Labs</a> convinced somebody at Paypal to hire them and found FIDO. Why Google joined despite Google's support for the <a href="http://www.w3.org/2012/webcrypto/" target="_blank">W3C WebCrypto</a> group I have no idea.<br />
<br />
The W3C WebCrypto group is were this belongs. This might need <a href="http://www.w3.org/2011/11/webcryptography-charter.html" target="_blank">rechartering</a> of the group. But that is doable. Especially if the proposal is backed by a prototype implementation. Especially if it is backed by by Paypal, Lenovo, Google, Nxp and <a href="http://www.fidoalliance.org/members.html" target="_blank">others</a>.<br />
<br />
I believe that we need better authentication methods beyond username and password. I think that bring your own (hardware) identiy might work to that goal. I believe that mobile phones, and SIM cards and NFC help to achieve this. I believe that the mobile wallet is the right user interface to choose your identity.<br />
<br />
I believe that doing it in a closed group is not the right way. <br />
<br />
<br />
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXg2XKaq5Xo2R4hyvSUO0EAI3PqCCi5zz-WrHzH2e4L6V2QDznBmtJCgH7bhDb9-IOq0ZSddsGlDNxxcwA1avp3IGlS28-kr2E5M3OBjdg5JnMxM6HYntu1dkN800DdHEwvWuWXg/s1600/nopasswords3.png" style="display: block; margin-left: auto; margin-right: auto;" /><br />
<br />Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-87558631738144518202012-11-08T13:24:00.000+01:002012-11-08T13:24:21.713+01:00Javascript API for OpenIDToo long ago I wrote about an Javascript API for openid:
<a href="http://ignisvulpis.blogspot.de/2011/03/all-those-nascars.html">all those NASCARs</a><br/><br/>
To repeat the main points:<br/><br/>
Sites currently have no easy way to detect support for openid</br>
The site can detect support for openid like so:<br/>
<pre>
if (window.openid) { don't show the nascar }<br/>
</pre>
The DOM level API that allows the site to query the preferred identity provider looks like this:<br/>
<pre>
window.openid.getPreferredOpenidProvider(callback);
</pre>
In a world of oauth2 and openid connect this could be generalized to:<br/>
https://openid.net/specs/openid-connect-standard-1_0.html#rf_prep
<pre>
var parameters = {};
parameters.response_type="id_token";
parameters.client_id="https://server.example.com/seminar/callback.html";
parameters.request = "eyJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOlwvXC9nYWJ1bm9taS5uZXRcL3NlbWluYXJcL3JzYV9wdWJsaWNfa2V5LnBlbSJ9.ewoJInJlc3BvbnNlX3R5cGUiOiAiaWRfdG9rZW4iLAoJInNjb3BlIjogIm9wZW5pZCIsCgkiY2xpZW50X2lkIjogImh0dHBzOi8vZ2FidW5vbWkubmV0L3NlbWluYXIvY2FsbGJhY2suaHRtbCIsCgkicG9saWN5X3VybCI6ICJodHRwczovL2dhYnVub21pLm5ldC9zZW1pbmFyL3BvbGljeS5odG1sIiwKCSJ1c2VyaW5mbyI6IHsKCQkiY2xhaW1zIjogewoJCQkibmFtZSI6IG51bGwsCgkJCSJlbWFpbCI6IG51bGwsCgkJCSJwaWN0dXJlIjogbnVsbAoJCX0KCX0sCgkicmVnaXN0cmF0aW9uIjogewoJCSJhcHBsaWNhdGlvbl9uYW1lIjogIlNhbXBsZSBTZW1pbmFyIiwKCQkibG9nb191cmwiOiAiaHR0cHM6Ly9nYWJ1bm9taS5uZXQvc2VtaW5hci9sb2dvLnBuZyIsCgkJIng1MDlfdXJsIjogImh0dHBzOi8vZ2FidW5vbWkubmV0L3NlbWluYXIvcnNhX3B1YmxpY19rZXkucGVtIgoJfQp9Cg.Faytuhwb2W4CWVz2-10umSieh-bqR7QXqU0bNF39u_D0mGoBD4e3X2b4jZNqPvPADSnQhlBGSJu189iFM5bwFzchnO-quCpj7T2CK_-wkrpL5LUn_WHYMmYlFadmb-a1p-TEo7exU9azMS9cT70-kHNqmTaJziZyiAMoJ0Q4TtyTt1Xbkknc_CQRug3ilNv3bEXSlOlva3HUOY7jQIbYMB3jDL3QxS1wbVYNAjOxCxCDmiNAUJA-BkYe6Tpyj-DUs57IM4wQSp64sqim8RqirJJfFb4bCbNTkC3G8sYfN2_1-qEDpOnWW7N3gjl174TWHbnzVLAZGg_rZm58-wHOLw";
parameters.state="509b9cafd3119";
parameters.nonce="509b9cafd34fd";
window.openid.connect(parameters, oc_callback);
</pre>
The callback <pre>oc_callback</pre> would be called with one parameter.
<pre>
function oc_callback(resp) {
// resp contains a signed then encrypted id_token in jw-* format
// https://tools.ietf.org/html/draft-ietf-jose-json-web-encryption
// https://tools.ietf.org/html/draft-ietf-jose-json-web-signature
// state and nonce are inside the resp parameter too
// need a private key to decrypt it so forward it to my own validation endpoint
$.post("validate.php", { resp: resp },
function(id_token) {
alert("returned id_token: " + id_token);
});
}
</pre>
The general idea is: put all http request parameters which are defined in openid connect into the request object. Put all the http respones parameters into the response object.<br/><br/>
I think we need an Javascript API for identity that is supported by browsers.
BrowserID/Persona and AccountChooser do something in this direction but not enough.
Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-12010128327781330632012-06-01T15:41:00.000+02:002012-06-01T19:37:13.688+02:00ECDH-ES for JSON Web EncryptionThe JSON WebToken spec RECOMMENDS that <a href="http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman">ECDH-ES</a> is implemented. Here we go:
<br />
<br />
Here are the relevant snippets from the <a href="https://tools.ietf.org/id/draft-ietf-jose-json-web-algorithms-02.html">JWA</a> spec:<br />
<br />
<br />
<b>4.1. "alg" (Algorithm) Header Parameter Values for JWE</b> <br />
<table border="1" cellpadding="3" cellspacing="0" class="tt full center">
<thead>
<tr>
<th class="left">alg Parameter Value</th>
<th class="left">Key Encryption or Agreement Algorithm</th>
</tr>
</thead>
<tbody>
<tr>
<td class="left">ECDH-ES</td>
<td class="left">Elliptic Curve Diffie-Hellman Ephemeral Static, as defined in <a href="http://tools.ietf.org/html/rfc6090">RFC 6090</a> , and using the Concat KDF, as defined in Section 5.8.1 of <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST.800-56A</a>, where the Digest Method is SHA-256 and all OtherInfo parameters are the empty bit string</td>
</tr>
</tbody></table>
<b><br /><br />
4.6. Key Agreement with Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES)</b><br />
<br />
This section defines the specifics of agreeing upon a JWE CMK with Elliptic Curve Diffie-Hellman Ephemeral Static, as defined in <a href="http://tools.ietf.org/html/rfc6090">RFC 6090</a>, and using the Concat KDF, as defined in Section 5.8.1 of <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST.800-56A</a>, where the Digest Method is SHA-256 and all OtherInfo parameters are the empty bit string. The alg header parameter value ECDH-ES is used in this case.
A key of size 160 bits or larger MUST be used for the Elliptic Curve keys used with this algorithm. The output of the Concat KDF MUST be a key of the same length as that used by the enc algorithm.
An epk (ephemeral public key) value MUST only be used for a single key agreement transaction.
<br />
<br />
<b> Appendix B. Encryption Algorithm Identifier Cross-Reference </b>
<br />
<table border="1" cellpadding="3" cellspacing="0" class="tt full center">
<thead>
<tr>
<th class="left">Algorithm</th>
<th class="left">JWE</th>
<th class="left">XML ENC</th>
<th class="left">JCA</th>
</tr>
</thead>
<tbody>
<tr>
<td class="left">Elliptic Curve Diffie-Hellman Ephemeral Static</td>
<td class="left">ECDH-ES</td>
<td class="left">http://www.w3.org/2009/xmlenc11#ECDH-ES</td>
<td class="left">TBD</td>
</tr>
</tbody></table>
<br />
<br />
I could not find a Java implementation in JavaSE and the <a href="http://bouncycastle.org/java.html">Bouncycastle</a> library does not seem to have one neither.
Bouncycastle does implement keyderivation functions but not the one from NIST.800-56A.
Valuable input came from this webpage "<a href="http://www.di-mgt.com.au/cryptoKDFs.html">Key Derivation Functions: How many KDFs are there?</a>".
Taking the Bouncycasle implementation and converting it into KDFconcat is easy and here it is:
<a href="https://code.google.com/p/openinfocard/source/browse/trunk/src/org/xmldap/crypto/KDFConcatGenerator.java">https://code.google.com/p/openinfocard/source/browse/trunk/src/org/xmldap/crypto/KDFConcatGenerator.java</a>
<br />
<br />
The next thing needed are some keypairs for the JUNIT test cases. I generated them using openssl.<br>
<blockquote>openssl ecparam -out key1.pem -name secp256r1 -genkey</blockquote>
and displayed them using
<pre> openssl ec -in key1.pem -text
read EC key
Private-Key: (256 bit)
priv:
07:2f:23:22:c0:e7:5e:0c:85:17:64:b4:21:81:99:
67:78:fd:22:59:2f:87:e5:d4:38:36:09:74:29:a1:
c3:fc
pub:
04:ed:3c:83:1b:f3:e1:05:9f:12:07:7f:4b:e4:fd:
fe:90:55:73:d1:c6:76:45:b4:7d:48:64:ea:17:9d:
de:99:86:a9:a6:ad:34:27:4a:80:fc:94:b3:a5:ef:
6c:6e:78:2c:22:7a:39:63:a6:a4:26:50:97:6d:a6:
ad:e9:90:a1:61
ASN1 OID: prime256v1
writing EC key
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAcvIyLA514MhRdktCGBmWd4/SJZL4fl1Dg2CXQpocP8oAoGCCqGSM49
AwEHoUQDQgAE7TyDG/PhBZ8SB39L5P3+kFVz0cZ2RbR9SGTqF53emYappq00J0qA
/JSzpe9sbngsIno5Y6akJlCXbaat6ZChYQ==
-----END EC PRIVATE KEY-----
</pre>
Too bad that the man page does not go into detail in what format priv and pub are... Read the <a href="http://www.openssl.org/source/openssl-1.0.1c.tar.gz">source</a>, Luke!
It seems that the priv key D is just the bytes in hex of the private key BigInteger. The public key seems to be something else but this is no problem because in ECC the public key is G*D where G is a curve parameter.
<br/>
So the two private keys are now defined <a href="https://code.google.com/p/openinfocard/source/browse/trunk/testsrc/org/xmldap/json/WebTokenTest.java#140">here</a> in the JUNIT tests. One is for the sender of the JWE the other for the recipient.
<pre>
static final String ec256_a_priv = "072f2322c0e75e0c851764b42181996778fd22592f87e5d43836097429a1c3fc";
static final String ec256_b_priv = "1a3eda89dc067871530601f934c6428574f837507c578e45bd10a29b2e019bfb";
</pre>
Now the public keys are computed like <a href="https://code.google.com/p/openinfocard/source/browse/trunk/testsrc/org/xmldap/json/WebTokenTest.java#257">this</a>:
<pre>
ASN1ObjectIdentifier oid = ECUtil.getNamedCurveOid("secp256r1");
X9ECParameters x9ECParameters = ECUtil.getNamedCurveByOid(oid);
byte[] ec256_a_priv_bytes = Hex.decode(ec256_a_priv);
ec256_a_D = new BigInteger(1, ec256_a_priv_bytes);
ECPoint pub = x9ECParameters.getG().multiply(ec256_a_D);
ec256_a_X = pub.getX().toBigInteger();
ec256_a_Y = pub.getY().toBigInteger();
</pre>
This gives the following jwtHeader for the first private key:
ECDH-ES jwtHeaderSegment: <pre>{"alg":"ECDH-ES",
"enc":"A256GCM",
"iv":"__79_Pv6-fg",
"crv":"secp256r1",
"x":"AO08gxvz4QWfEgd_S-T9_pBVc9HGdkW0fUhk6hed3pmG",
"y":"AKmmrTQnSoD8lLOl72xueCwiejljpqQmUJdtpq3pkKFh"}
</pre>
The spec says that the senders key pair is ephemeral and the recipient's key pair is static. So code using <a href="https://code.google.com/p/openinfocard/source/browse/trunk/src/org/xmldap/json/WebToken.java#696">this code</a> should generate one ephemeral EC key pair. Stuff the private key and the recipients public key into the encrypt function. These key parts are used for the key agreement. See the <a href="http://en.wikipedia.org/wiki/Elliptic_curve_Diffie%E2%80%93Hellman">wikipedia page</a> for a short explanation.
I will implement the "epk" header parameter at a later time. For now I use the X and Y format to transfer the ephemeral public key to the recipient.<br/>
Base64 encoding the header yields:
<pre>eyJhbGciOiJFQ0RILUVTIiwNCiJlbmMiOiJBMjU2R0NNIiwNCiJpdiI6Il9fNzlfUHY2LWZnIiwNCiJjcnYiOiJzZWNwMjU2cjEiLA0KIngiOiJBTzA4Z3h2ejRRV2ZFZ2RfUy1UOV9wQlZjOUhHZGtXMGZVaGs2aGVkM3BtRyIsDQoieSI6IkFLbW1yVFFuU29EOGxMT2w3Mnh1ZUN3aWVqbGpwcVFtVUpkdHBxM3BrS0ZoIn0</pre>
<br>
<br>
The next step in my interpretation of the spec is to generate the content encryption key using the key derivation function defined in the NIST paper.
The content encryption is done using the method specified in the enc parameter of the header here: A256GCM<br/>
For this method I need a 256bit == 32byte key and a 12 byte IV. So the call to the KDF <a href="https://code.google.com/p/openinfocard/source/browse/trunk/src/org/xmldap/json/WebToken.java#727">is</a>:<br/>
<pre>
ECDHBasicAgreement ecdhBasicAgreement = new ECDHBasicAgreement();
ecdhBasicAgreement.init(ecPrivateKeyParameters);
BigInteger z = ecdhBasicAgreement.calculateAgreement(ecPublicKeyParameters);
byte[] zBytes = BigIntegers.asUnsignedByteArray(z);
KDFConcatGenerator kdfConcatGenerator = new KDFConcatGenerator(kdfDigest);
kdfConcatGenerator.init(new KDFParameters(zBytes, null));
byte[] out = new byte[12 + (keylength / 8)];
kdfConcatGenerator.generateBytes(out, 0, out.length);
byte[] secretKeyBytes = new byte[keylength / 8];
byte[] ivBytes = new byte[12];
System.arraycopy(out, 0, ivBytes, 0, 12);
System.arraycopy(out, 12, secretKeyBytes, 0, secretKeyBytes.length);
</pre><br/>
Now a random 256bit AES key is generated and encrypted using the secret key and IV generated by the KDF.<br/>
For this content encryption key (base64url) <pre>
ECDH-ES contentEncryptionKey=Y8-fcu11np1l3qlgpGq0XF58Cv2n4DOJ8lkdl2gRXgI</pre>
the values of the key segment and the jwe crypto segment are this: <pre>
ECDH-ES jwtSymmetricKeySegment base64: _vZ-N5fs3_uJ9o-woDOzKZBQopZRi4EfZVNB4UWqdCjappfoOFCZPTUBDruWAtWY
ECDH-ES jwtCryptoSegment base64: psSi2xa7oY1pmK1m9GGXREr9YB6QUdOtK_Jl_nnKYpmKGHL577tUdadK8H_yacb78bBlyTnrTx51pmxyo6UJMM9c_P-lOfMiMslvS-3t1vD5HiOq0Rg
</pre>
Please use the <a href="http://www.ietf.org/mail-archive/web/jose/current/maillist.html">IETF JOSE mailing list</a> for comments and suggestions.
<br><br>
Special thanks to <a href="http://self-issued.info/">Mike Jones</a> for writing most of the JW* specs text and to <a href="http://www.thread-safe.com/">John Bradley</a> for being a fountain of knowledge in all things crypto and identity management protocols and formats. Not to forget <a href="http://nat.sakimura.org/">Nat Sakimura</a> for starting the <a href="http://lists.openid.net/mailman/listinfo/openid-specs-ab">OpenID Artifact Binding WG</a> which now does all the <a href="http://openid.net/connect/">OpenID Connect</a> work. Especially for mobile devices we need simple, light weight protocols and formats. JW* and especially ECDH-ES are important for mobile.Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-29448003290249793372012-05-24T21:50:00.000+02:002012-05-24T21:50:35.267+02:00Playing with Google's Identity Toolkit on openinfocard.orgToday I retried Google's Identity Toolkit.
<br />
<a href="https://developers.google.com/identity-toolkit/v1/acguide">https://developers.google.com/identity-toolkit/v1/acguide</a><br />
So I had to undust my rudimentary PHP knowledge and write some scripts and minimal html pages.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhllrNfg9xkVJPbxAu9baUidZ0XXwTSMb7PL1Q45iA9oH7E_ck9NKnqvZt0mHVoI7SezeBKKflPiC9R3KmgTlIbxapwpvJG2qFuwOVQwFZX2ZcCp6YoBp1YkvLZigSYbcpRxXsB6w/s1600/git-startpage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhllrNfg9xkVJPbxAu9baUidZ0XXwTSMb7PL1Q45iA9oH7E_ck9NKnqvZt0mHVoI7SezeBKKflPiC9R3KmgTlIbxapwpvJG2qFuwOVQwFZX2ZcCp6YoBp1YkvLZigSYbcpRxXsB6w/s320/git-startpage.png" width="320" /></a></div>
<br />
Clicking the key hole icon opens the account chooser.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiW9ktdufDINCAsTs-brgP_hVEO8KBzYEifqdxUx1pzCweEd8EjSFwGkCEa_jz64X-nkC4jdEshUkh-VLsOmMB8Y5S-nLMG19OPwtNvCKRRklVZ-_76dXq2mz4HmziPKqV8WwoxQ/s1600/git-signin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiW9ktdufDINCAsTs-brgP_hVEO8KBzYEifqdxUx1pzCweEd8EjSFwGkCEa_jz64X-nkC4jdEshUkh-VLsOmMB8Y5S-nLMG19OPwtNvCKRRklVZ-_76dXq2mz4HmziPKqV8WwoxQ/s320/git-signin.png" width="320" /></a></div>
<br />
I choose GMail and login to Google.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAC2LddwdZrnb-ygEtMIwyQddIBYcyAPtmsAUKSoy_STgh0BZIGtaobDneSEDmBoz0Ny1BP9rmdpIcp6HbXDWIHHwpj-zbrRcxcW3jJ7eOBr3IbEbkRngSV0ASwKPtB_3ZWZ69xg/s1600/idp-signin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAC2LddwdZrnb-ygEtMIwyQddIBYcyAPtmsAUKSoy_STgh0BZIGtaobDneSEDmBoz0Ny1BP9rmdpIcp6HbXDWIHHwpj-zbrRcxcW3jJ7eOBr3IbEbkRngSV0ASwKPtB_3ZWZ69xg/s320/idp-signin.png" width="276" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzdJLP-J5vp3juVyUjh4c1AwIyNCMH9erqLKPiWNsQYRyfZd-aDQhTBvRYt0ZJEf6XUtBnKEqvy83polCWAQBEYsr8O6wHdCYLOoQCar21JjJB4vXJxsGK6x7CKnyg9fhyg5YPQQ/s1600/signingin.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzdJLP-J5vp3juVyUjh4c1AwIyNCMH9erqLKPiWNsQYRyfZd-aDQhTBvRYt0ZJEf6XUtBnKEqvy83polCWAQBEYsr8O6wHdCYLOoQCar21JjJB4vXJxsGK6x7CKnyg9fhyg5YPQQ/s320/signingin.png" width="320" /></a></div>
<br />
This is the result page. My site now knows some attributes about me like verifiedEmail, display name and imageUrl etc.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8JoR77JHe5xUWKOL3ELDJ6DqIrCJD_EJ44DBjQrdr4H04wz37nEJ3N8XYMjgwn9Pr52eHaBsfGN6cg0xGtt9Mse4oGfA9-zwTWRnqkdOgRwYMMcAI7QbjIvDHJHNxNnXKECAh1Q/s1600/home.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8JoR77JHe5xUWKOL3ELDJ6DqIrCJD_EJ44DBjQrdr4H04wz37nEJ3N8XYMjgwn9Pr52eHaBsfGN6cg0xGtt9Mse4oGfA9-zwTWRnqkdOgRwYMMcAI7QbjIvDHJHNxNnXKECAh1Q/s320/home.png" width="320" /></a></div>
<br />
Next task: Repeat and rinse with <a href="http://accountchooser.net/">http://accountchooser.net/</a>Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.comtag:blogger.com,1999:blog-37220752.post-15097017608201708142012-05-02T17:06:00.000+02:002012-05-02T17:06:11.497+02:00Debugging OAuth2 SSL Connections<div class="separator" style="clear: both;">
<a href="http://hueniverse.com/wp-content/uploads/2010/05/OAuth2.png" imageanchor="1"><img border="0" height="100" src="http://hueniverse.com/wp-content/uploads/2010/05/OAuth2.png" style="float: right;" width="100" /></a></div>
Debugging SSL protected protocols like oauth2 can be a problem but it is not
entirely impossible nor hard to do.<br />
<br />
One way to do it is to spoof the certificates the protocol relies on to protect the communication. The certificates are used by the client
to verify that the server is the endpoint it is supposed to be talking to and to encrypt the communication. A
good description for the Android operating system is given in this blog post (<a href="http://myhowto.org/java/81-intercepting-and-decrypting-ssl-communications-between-android-phone-and-3rd-party-server/" title="Permanent link to Intercepting and decrypting SSL communications between Android phone and 3rd party server">Intercepting
and decrypting SSL communications between Android phone and 3rd party server</a>).
Nobody can blame Android for being picked here as an example and ways to do
this exist for all operating systems. Yes, to install the certs you need root
access; but it well may be that you have that and want to help a friend to
debug their installed application on your phone. Even if the client is running
on a server it may be worthwhile to debug the network traffic to find certain
errors in the client implementation. An error specific to an oauth
implementation might be that your friend has a typo in the cliend_id or
client_secret and the authorization server is rejecting requests because of
that.<br />
It might be hard for you to verify client_id and client_secret by analyzing
the client. Maybe they are stored on a UICC or stored encrypted in the file system (and
the keystore password is not "changeit") and are only decrypted and
used when a resource owner uses the client.<br />
By analyzing the SSL traffic you can help to find this kind of bug and all
other related to protocol issues.<br />
<br />
But maybe you don't have an SSL server to capture the plain text from an SSL
connection?! Then another path you might take is to swap the client's SSL
implementation with your own. You don't have to change the client's code or analyze
the client's memory. Building your own version of most operating systems with
your own SSL implementation is not that hard to do. Or maybe you can just
register your SSL implementation to be used with all client code? Or you can
swap a library?<br />
There are more ways to achieve your goal.<br />
<br />
But make sure that you have your friend's permission first. Not everybody might be happy with the fact that you now know the client_id and client_secret.<br />
<br />
Have fun!<br />
<br />
<div class="MsoNormal">
<br /></div>Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-76348036378883909802012-04-28T07:08:00.001+02:002012-04-28T07:08:08.233+02:00Identity Management @ RSA 2012 EuropeSharpen your keyboard and <a href="http://www.rsaconference.com/events/2012/europe/call-for-speakers.htm">submit</a> a paper for the Identity Management track at RSA Conference Europe 2012. The leading conference on security and all things you need to know.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ezkxtXSmAjcPyxviugu6CDcB8fg3_TN5uY3Dp-7FgBlR-Q8CZs9rrQZW3MQ3Wf3zGu5l5XhpyYl7EWEjP5uxNw1G9DJkIev3cPr281YdvyX0rcrq-BPXgZIXxKRWETfBsemzOQ/s1600/RSA-2012-europe.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="68" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ezkxtXSmAjcPyxviugu6CDcB8fg3_TN5uY3Dp-7FgBlR-Q8CZs9rrQZW3MQ3Wf3zGu5l5XhpyYl7EWEjP5uxNw1G9DJkIev3cPr281YdvyX0rcrq-BPXgZIXxKRWETfBsemzOQ/s320/RSA-2012-europe.png" width="320" /></a></div>
<br />
<blockquote class="tr_bq">
From the<a href="http://www.rsaconference.com/events/2012/europe/call-for-speakers/topic-descriptions.htm"> topic description</a>:
<b>Identity Management </b><br />
Identity Management covers issues of access control,
authentication, identification technologies & protocols. Sessions on
Identity and Access Management (IAM) fit here, along with sessions on
IAM standards and architecture. This topic also covers issues such as
credential management, multifactor authentication and new methods of
authentication.</blockquote>
The Call for Speakers closes on <strong>Friday 18th May</strong>Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-87038462928024914692012-04-26T19:10:00.000+02:002012-04-26T19:10:55.117+02:00Myhabit.com unconfusedHere the unconfusing part with was censored in one <a href="http://connectid.blogspot.ca/2012/04/taxonomy-of-confusion.html">other</a> post about the same UI.
<br />
<div class="separator" style="clear: both; color: black; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
</a><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
</a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s320/myhabit.png" width="244" /></a></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWVelQRT0k4WHosBHKLH78ylPkl4s4WhoRklhA-UqqiqKv7CPTgYd924UA6Qkn6UQICVBxkj8_LT5wF0p9SIHlLSOs7IIpDdzNAy_KyH-2to2-IIjdgMHUxN_G2asD956iltAzhA/s1600/myhabit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;">
</a>
Note the Amazon favicon and URL.Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0tag:blogger.com,1999:blog-37220752.post-75525452577653065362012-01-22T11:24:00.003+01:002012-01-22T11:24:59.274+01:00OpenID Connect Test Servers<br />Here are some experimental <a href="http://openid.net/connect/">OpenID Connect</a> server configurations:<br />
<pre> </pre>
<pre><b>https://connect-op.heroku.com/.well-known/openid-configuration</b></pre>
<pre> </pre>
<blockquote class="tr_bq">
<pre><span class="sBrace structure-1" id="s-1">{</span>
<span> </span><span class="sObjectK" id="s-2">"version"</span><span class="sColon" id="s-3">:</span><span class="sObjectV" id="s-4">"3.0"</span><span class="sComma" id="s-5">,</span>
<span> </span><span class="sObjectK" id="s-6">"issuer"</span><span class="sColon" id="s-7">:</span><span class="sObjectV" id="s-8">"<a class="vglnk" href="https://connect-op.heroku.com/" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com</a>"</span><span class="sComma" id="s-9">,</span>
<span> </span><span class="sObjectK" id="s-10">"authorization_endpoint"</span><span class="sColon" id="s-11">:</span><span class="sObjectV" id="s-12">"<a class="vglnk" href="https://connect-op.heroku.com/authorizations/new" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/authorizations/new</a>"</span><span class="sComma" id="s-13">,</span>
<span> </span><span class="sObjectK" id="s-14">"token_endpoint"</span><span class="sColon" id="s-15">:</span><span class="sObjectV" id="s-16">"<a class="vglnk" href="https://connect-op.heroku.com/access_tokens" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/access_tokens</a>"</span><span class="sComma" id="s-17">,</span>
<span> </span><span class="sObjectK" id="s-18">"userinfo_endpoint"</span><span class="sColon" id="s-19">:</span><span class="sObjectV" id="s-20">"<a class="vglnk" href="https://connect-op.heroku.com/user_info" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/user_info</a>"</span><span class="sComma" id="s-21">,</span>
<span> </span><span class="sObjectK" id="s-22">"check_id_endpoint"</span><span class="sColon" id="s-23">:</span><span class="sObjectV" id="s-24">"<a class="vglnk" href="https://connect-op.heroku.com/id_token" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/id_token</a>"</span><span class="sComma" id="s-25">,</span>
<span> </span><span class="sObjectK" id="s-26">"registration_endpoint"</span><span class="sColon" id="s-27">:</span><span class="sObjectV" id="s-28">"<a class="vglnk" href="https://connect-op.heroku.com/connect/client" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/connect/client</a>"</span><span class="sComma" id="s-29">,</span>
<span> </span><span class="sObjectK" id="s-30">"scopes_supported"</span><span class="sColon" id="s-31">:</span><span class="sBracket structure-2" id="s-32">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-33">"openid"</span><span class="sComma" id="s-34">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-35">"profile"</span><span class="sComma" id="s-36">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-37">"email"</span><span class="sComma" id="s-38">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-39">"address"</span><span class="sComma" id="s-40">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-41">"PPID"</span>
<span> </span><span class="sBracket structure-2" id="s-42">]</span><span class="sComma" id="s-43">,</span>
<span> </span><span class="sObjectK" id="s-44">"response_types_supported"</span><span class="sColon" id="s-45">:</span><span class="sBracket structure-2" id="s-46">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-47">"code"</span><span class="sComma" id="s-48">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-49">"token"</span><span class="sComma" id="s-50">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-51">"id_token"</span><span class="sComma" id="s-52">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-53">"code token"</span><span class="sComma" id="s-54">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-55">"code id_token"</span><span class="sComma" id="s-56">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-57">"id_token token"</span>
<span> </span><span class="sBracket structure-2" id="s-58">]</span><span class="sComma" id="s-59">,</span>
<span> </span><span class="sObjectK" id="s-60">"user_id_types_supported"</span><span class="sColon" id="s-61">:</span><span class="sBracket structure-2" id="s-62">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-63">"public"</span><span class="sComma" id="s-64">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-65">"pairwise"</span>
<span> </span><span class="sBracket structure-2" id="s-66">]</span><span class="sComma" id="s-67">,</span>
<span> </span><span class="sObjectK" id="s-68">"x509_url"</span><span class="sColon" id="s-69">:</span><span class="sObjectV" id="s-70">"<a class="vglnk" href="https://connect-op.heroku.com/cert.pem" rel="nofollow" title="Link added by VigLink">https://connect-op.heroku.com/cert.pem</a>"</span>
<span class="sBrace structure-1" id="s-71">}</span></pre>
</blockquote>
<pre><b><span class="sBrace structure-1" id="s-71">https://openidconnect.info/.well-known/openid-configuration</span></b></pre>
<pre><span class="sBrace structure-1" id="s-71"> </span></pre>
<blockquote class="tr_bq">
<pre><span class="sBrace structure-1" id="s-1">{</span>
<span> </span><span class="sObjectK" id="s-2">"version"</span><span class="sColon" id="s-3">:</span><span class="sObjectV" id="s-4">"3.0"</span><span class="sComma" id="s-5">,</span>
<span> </span><span class="sObjectK" id="s-6">"issuer"</span><span class="sColon" id="s-7">:</span><span class="sObjectV" id="s-8">"<a class="vglnk" href="https://openidconnect.info/" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/</a>"</span><span class="sComma" id="s-9">,</span>
<span> </span><span class="sObjectK" id="s-10">"authorization_endpoint"</span><span class="sColon" id="s-11">:</span><span class="sObjectV" id="s-12">"<a class="vglnk" href="https://openidconnect.info/connect/authorize" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/connect/authorize</a>"</span><span class="sComma" id="s-13">,</span>
<span> </span><span class="sObjectK" id="s-14">"token_endpoint"</span><span class="sColon" id="s-15">:</span><span class="sObjectV" id="s-16">"<a class="vglnk" href="https://openidconnect.info/connect/token" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/connect/token</a>"</span><span class="sComma" id="s-17">,</span>
<span> </span><span class="sObjectK" id="s-18">"user_info_endpoint"</span><span class="sColon" id="s-19">:</span><span class="sObjectV" id="s-20">"<a class="vglnk" href="https://openidconnect.info/connect/userinfo" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/connect/userinfo</a>"</span><span class="sComma" id="s-21">,</span>
<span> </span><span class="sObjectK" id="s-22">"check_id_endpoint"</span><span class="sColon" id="s-23">:</span><span class="sObjectV" id="s-24">"<a class="vglnk" href="https://openidconnect.info/connect/check_session" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/connect/check_session</a>"</span><span class="sComma" id="s-25">,</span>
<span> </span><span class="sObjectK" id="s-26">"registration_endpoint"</span><span class="sColon" id="s-27">:</span><span class="sObjectV" id="s-28">"<a class="vglnk" href="https://openidconnect.info/connect/register" rel="nofollow" title="Link added by VigLink">https://openidconnect.info/connect/register</a>"</span><span class="sComma" id="s-29">,</span>
<span> </span><span class="sObjectK" id="s-30">"scopes_supported"</span><span class="sColon" id="s-31">:</span><span class="sBracket structure-2" id="s-32">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-33">"openid"</span><span class="sComma" id="s-34">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-35">"profile"</span><span class="sComma" id="s-36">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-37">"email"</span><span class="sComma" id="s-38">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-39">"address"</span><span class="sComma" id="s-40">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-41">"PPID"</span>
<span> </span><span class="sBracket structure-2" id="s-42">]</span><span class="sComma" id="s-43">,</span>
<span> </span><span class="sObjectK" id="s-44">"flows_supported"</span><span class="sColon" id="s-45">:</span><span class="sBracket structure-2" id="s-46">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-47">"code"</span><span class="sComma" id="s-48">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-49">"token"</span><span class="sComma" id="s-50">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-51">"code id_token"</span><span class="sComma" id="s-52">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-53">"token id_token"</span>
<span> </span><span class="sBracket structure-2" id="s-54">]</span><span class="sComma" id="s-55">,</span>
<span> </span><span class="sObjectK" id="s-56">"identifiers_supported"</span><span class="sColon" id="s-57">:</span><span class="sBracket structure-2" id="s-58">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-59">"public"</span><span class="sComma" id="s-60">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-61">"ppid"</span>
<span> </span><span class="sBracket structure-2" id="s-62">]</span>
<span class="sBrace structure-1" id="s-63">}</span></pre>
</blockquote>
<pre><span class="sBrace structure-1" id="s-71"><b>https://connect.openid4.us/.well-known/openid-configuration</b></span></pre>
<pre><span class="sBrace structure-1" id="s-71">
</span></pre>
<blockquote class="tr_bq">
<pre><span class="sBrace structure-1" id="s-1">{</span>
<span> </span><span class="sObjectK" id="s-2">"version"</span><span class="sColon" id="s-3">:</span><span class="sObjectV" id="s-4">"3.0"</span><span class="sComma" id="s-5">,</span>
<span> </span><span class="sObjectK" id="s-6">"issuer"</span><span class="sColon" id="s-7">:</span><span class="sObjectV" id="s-8">"https:\/\/connect.openid4.us"</span><span class="sComma" id="s-9">,</span>
<span> </span><span class="sObjectK" id="s-10">"authorization_endpoint"</span><span class="sColon" id="s-11">:</span><span class="sObjectV" id="s-12">"https:\/\/connect.openid4.us\/abop\/op.php\/auth"</span><span class="sComma" id="s-13">,</span>
<span> </span><span class="sObjectK" id="s-14">"token_endpoint"</span><span class="sColon" id="s-15">:</span><span class="sObjectV" id="s-16">"https:\/\/connect.openid4.us\/abop\/op.php\/token"</span><span class="sComma" id="s-17">,</span>
<span> </span><span class="sObjectK" id="s-18">"userinfo_endpoint"</span><span class="sColon" id="s-19">:</span><span class="sObjectV" id="s-20">"https:\/\/connect.openid4.us\/abop\/op.php\/userinfo"</span><span class="sComma" id="s-21">,</span>
<span> </span><span class="sObjectK" id="s-22">"check_id_endpoint"</span><span class="sColon" id="s-23">:</span><span class="sObjectV" id="s-24">"https:\/\/connect.openid4.us\/abop\/op.php\/check_id"</span><span class="sComma" id="s-25">,</span>
<span> </span><span class="sObjectK" id="s-26">"refresh_session_endpoint"</span><span class="sColon" id="s-27">:</span><span class="sObjectV" id="s-28">"https:\/\/connect.openid4.us\/abop\/op.php\/refreshsession"</span><span class="sComma" id="s-29">,</span>
<span> </span><span class="sObjectK" id="s-30">"end_session_endpoint"</span><span class="sColon" id="s-31">:</span><span class="sObjectV" id="s-32">"https:\/\/connect.openid4.us\/abop\/op.php\/endsession"</span><span class="sComma" id="s-33">,</span>
<span> </span><span class="sObjectK" id="s-34">"jwk_url"</span><span class="sColon" id="s-35">:</span><span class="sObjectV" id="s-36">"https:\/\/connect.openid4.us\/connect4us.jwk"</span><span class="sComma" id="s-37">,</span>
<span> </span><span class="sObjectK" id="s-38">"jwk_encryption_url"</span><span class="sColon" id="s-39">:</span><span class="sObjectV" id="s-40">"https:\/\/connect.openid4.us\/connect4us.jwk"</span><span class="sComma" id="s-41">,</span>
<span> </span><span class="sObjectK" id="s-42">"x509_url"</span><span class="sColon" id="s-43">:</span><span class="sObjectV" id="s-44">"https:\/\/connect.openid4.us\/connect4us.pem"</span><span class="sComma" id="s-45">,</span>
<span> </span><span class="sObjectK" id="s-46">"x509_encryption_url"</span><span class="sColon" id="s-47">:</span><span class="sObjectV" id="s-48">"https:\/\/connect.openid4.us\/connect4us.pem"</span><span class="sComma" id="s-49">,</span>
<span> </span><span class="sObjectK" id="s-50">"registration_endpoint"</span><span class="sColon" id="s-51">:</span><span class="sObjectV" id="s-52">"https:\/\/connect.openid4.us\/abop\/op.php\/registration"</span><span class="sComma" id="s-53">,</span>
<span> </span><span class="sObjectK" id="s-54">"scopes_supported"</span><span class="sColon" id="s-55">:</span><span class="sBracket structure-2" id="s-56">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-57">"openid"</span><span class="sComma" id="s-58">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-59">"profile"</span><span class="sComma" id="s-60">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-61">"email"</span><span class="sComma" id="s-62">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-63">"address"</span>
<span> </span><span class="sBracket structure-2" id="s-64">]</span><span class="sComma" id="s-65">,</span>
<span> </span><span class="sObjectK" id="s-66">"response_types_supported"</span><span class="sColon" id="s-67">:</span><span class="sBracket structure-2" id="s-68">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-69">"code"</span><span class="sComma" id="s-70">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-71">"token"</span><span class="sComma" id="s-72">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-73">"id_token"</span>
<span> </span><span class="sBracket structure-2" id="s-74">]</span><span class="sComma" id="s-75">,</span>
<span> </span><span class="sObjectK" id="s-76">"acrs_supported"</span><span class="sColon" id="s-77">:</span><span class="sBracket structure-2" id="s-78">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-79">"http:\/\/www.idmanagement.gov\/schema\/2009\/05\/icam\/openid-trust-level1.pdf"</span>
<span> </span><span class="sBracket structure-2" id="s-80">]</span><span class="sComma" id="s-81">,</span>
<span> </span><span class="sObjectK" id="s-82">"user_id_types_supported"</span><span class="sColon" id="s-83">:</span><span class="sBracket structure-2" id="s-84">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-85">"public"</span><span class="sComma" id="s-86">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-87">"pairwise"</span>
<span> </span><span class="sBracket structure-2" id="s-88">]</span><span class="sComma" id="s-89">,</span>
<span> </span><span class="sObjectK" id="s-90">"userinfo_algs_supported"</span><span class="sColon" id="s-91">:</span><span class="sBracket structure-2" id="s-92">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-93">"HS256"</span><span class="sComma" id="s-94">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-95">"RS256"</span><span class="sComma" id="s-96">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-97">"A128CBC"</span><span class="sComma" id="s-98">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-99">"A256CBC"</span><span class="sComma" id="s-100">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-101">"A128KW"</span><span class="sComma" id="s-102">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-103">"RSA1_5"</span>
<span> </span><span class="sBracket structure-2" id="s-104">]</span><span class="sComma" id="s-105">,</span>
<span> </span><span class="sObjectK" id="s-106">"id_token_algs_supported"</span><span class="sColon" id="s-107">:</span><span class="sBracket structure-2" id="s-108">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-109">"HS256"</span><span class="sComma" id="s-110">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-111">"RS256"</span><span class="sComma" id="s-112">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-113">"A128CBC"</span><span class="sComma" id="s-114">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-115">"A256CBC"</span><span class="sComma" id="s-116">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-117">"A128KW"</span><span class="sComma" id="s-118">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-119">"RSA1_5"</span>
<span> </span><span class="sBracket structure-2" id="s-120">]</span><span class="sComma" id="s-121">,</span>
<span> </span><span class="sObjectK" id="s-122">"request_object_algs_supported"</span><span class="sColon" id="s-123">:</span><span class="sBracket structure-2" id="s-124">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-125">"HS256"</span><span class="sComma" id="s-126">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-127">"RS256"</span><span class="sComma" id="s-128">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-129">"A128CBC"</span><span class="sComma" id="s-130">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-131">"A256CBC"</span><span class="sComma" id="s-132">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-133">"A128KW"</span><span class="sComma" id="s-134">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-135">"RSA1_5"</span>
<span> </span><span class="sBracket structure-2" id="s-136">]</span><span class="sComma" id="s-137">,</span>
<span> </span><span class="sObjectK" id="s-138">"token_endpoint_auth_types_supported"</span><span class="sColon" id="s-139">:</span><span class="sBracket structure-2" id="s-140">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-141">"client_secret_post"</span><span class="sComma" id="s-142">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-143">"client_secret_basic"</span><span class="sComma" id="s-144">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-145">"client_secret_jwt"</span><span class="sComma" id="s-146">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-147">"private_key_jwt"</span>
<span> </span><span class="sBracket structure-2" id="s-148">]</span><span class="sComma" id="s-149">,</span>
<span> </span><span class="sObjectK" id="s-150">"token_endpoint_auth_algs_supported"</span><span class="sColon" id="s-151">:</span><span class="sBracket structure-2" id="s-152">[</span>
<span> </span><span> </span><span class="sArrayV" id="s-153">"HS256"</span><span class="sComma" id="s-154">,</span>
<span> </span><span> </span><span class="sArrayV" id="s-155">"RS256"</span>
<span> </span><span class="sBracket structure-2" id="s-156">]</span>
<span class="sBrace structure-1" id="s-157">}</span></pre>
</blockquote>
<pre><b><span class="sBrace structure-1" id="s-157"> Happy testing!</span></b></pre>
<pre><span class="sBrace structure-1" id="s-157"> </span></pre>
<pre><span class="sBrace structure-1" id="s-71">
</span></pre>
<pre><span class="sBrace structure-1" id="s-71"> </span> </pre>Anonymoushttp://www.blogger.com/profile/01265275474642785203noreply@blogger.com0