The Developer Documentation

How to use cipherwallet services.

Cipher-whatlet?

Cipherwallet is a digital wallet application, living on mobile devices. People use it store their personal data, like name, addresses, phone numbers and credit cards, Perhaps more importantly, cipherwallet can also store secret access keys to their user's favorite websites. To obtain user's data from their mobile device, websites display a specially crafted QR code, obtained from the cipherwallet API. An user scans this code with the mobile cipherwallet app, selects and approves the data to be sent out, and just like that, a signup form on the computer's screen is filled in, a payment for the virtual shopping cart is made, or a touch-free login operation is magically executed. Sounds cool? OK, then let's see how we can integrate cipherwallet with your website. But first, let's have a...

20,000ft Overview

At the time of this writing, cipherwallet provides 3 major services. From the easiest to understand, to the most powerful and valuable, they are:

  • the checkout service;
  • the signup service;
  • aaaand, the login service.

For the cipherwallet's checkout service, your website will display a QR code image that represents, in a graphic format, the address of your website, an identifier of the web session in progress, and a list of data items needed to complete the checkout operation. Let's say the user filled up a virtual shopping cart on your super awesome e-commerce website, acme-bumpchins.com, and is ready to pay for their pile of, uh... stuff. (You sell stuff, right?) So the QR code you display would indicate:

  • your website, acme-bumpchins.com (because you don't want the user to spend their money on someone else's site);
  • the session ID, or the shopping cart ID (because you don't want the user to pay big bucks for some other user's purchase);
  • the information that you need from the user, like credit card number and expiration, email, phone, and shipping address (because you do want their money, and yeah, you do have the intention to ship their product).

The user scans the QR code with the cipherwallet mobile app, selects the data requested, and submits it to your acme-bumpchins.com website. Your website also receives the enough information to identify the user's session or their shopping cart. As such, it can auto-fill the form fields on the user's checkout page, and (optionally) it can even simulate that the user pressed the "pay" button. Great way to make it easier for your impulse buyer (a.k.a. user) to send over all the data that you need, and great way to reduce the shopping cart abandonment.

The cipherwallet signup service is... that's right, you got it. It's almost the same thing as the checkout service, but applied to the acme-bumpchins.com's signup page. What happens, in addition to transferring the user's personal data, is that your website will push back to the mobile device a set of credentials to be used, in the future, for cipherwallet-powered logins. So not only that your new users will find it easy to fill in your website's signup form, but they will also be ready to go for the cipherwallet logins.

This brings us to the third cipherwallet service - the login. Which is fundamentally different, because the cipherwallet mobile application doesn't, in fact, store usernames and passwords for various website. Instead, it stores an anonymous user ID, and a secret key, obtained during the signup process mentioned above (we will explain why this is better). The QR symbol displayed on the login page only encodes information about your website, and about the browser's session in progress. When the code is scanned, the cipherwallet mobile app looks up the credentials for acme-bumpchins.com, and uses the secret key to encrypt some random information, obtaining a signature. The random information is transmitted in clear, along with the signature, to your acme-bumpchins.com website. On the server side, your website encrypts the same random information, with the same user's secret key; if it obtains the same signature, that means the user can be trusted, and your website can consider him or her authenticated.

Let's pull up the sleeves, and get into more details.

The Dashboard

The dashboard is a management tool for your cipherwallet services and your cipherwallet customer account. Obviously, you need to sign up and log in to the ciperwallet website to use it.

Usage Reports

This area shows quick glance statistics about your traffic for a day, a week or a month's worth of traffic. (not implemented yet)

Services

The services tab lets you configure and manage the cipherwallet services you will be using. Each service has a service definition, which acts as a sort of template for how the conversation with the mobile application will work. When you create a service definition, some of the values will be pre-populated, but you can change them. Additionally, when your web application will request a QR code, you can send values that will override the service definition settings.

For every service, you will need to provide:

  • Service type: checkout, signup, login, or registration. (We talked about the first 3, we will describe the registration services later.)
  • Info URL: it points to a web page that displays helpful information to the user, about your checkout service. You typically hyperlink this page directly from your website (for example, when the user clicks on the QR code image), but this page is also launched in the user's mobile browser, when the QR code is scanned with a QR scanner app other than cipherwallet. So make sure your page looks ok both on a computer browser, and on a mobile browser.
  • Callback URL: it's an API URL that you will need to implement as one of your web services. The cipherwallet mobile app will hit this URL with a POST request, to transmit the checkout data selected by the user. Make sure that you provide a secure (https) URL, otherwise the cipherwallet mobile app will show a big red warning to the user about the connection not being secured.
  • Display: is a freeform text field where you can enter a message for the mobile app user. The message is displayed at the top of the screen where the data selection is made, so it's a good place to give the user a hint on how you are going to use the data they transmit (but you should keep it very short though). Use a double backslash as a placeholder for a line break.
Note: the cipherwallet dashboard makes sure that the Info URL and Callback URL are available, by sending a HEAD request; implement a 200 OK response for this request type, so that you don't see a warning indicator.
Note: login and registration services don't display a data selection form, so there is no Display option for them.

For some services (notably, signup and checkout), you also need to add a set of parameters; each parameter indicates a data item that you request from the user. For each parameter, you need to select:

  • a name: this is the name of the data item that will get returned to your web service from the mobile app.
  • a type: what kind of data this parameter holds (we will come back with details).
  • a label: a short description about how this parameter will be used, shown on the mobile app data selection screen (for example, "shipping address").
  • whether you consider the parameter optional or not (e.g. you can ask the user for their birthday on the checkout page, but you wouldn't consider it required).

The order in which the parameters will appear on the cipherwallet mobile app's screen is the order in which they're listed in the service definition. You can change the order by moving your parameters up and down with the arrows.

Subscription Details

Cipherwallet has a free usage tier, featuring a limited number of requests, so you can integrate with your web applications. When you sign up as a customer, this is the level of service you will be placed on. Once you're confident about your integration, add a credit card to your account, and you may select other usage tiers that are more appropriate for your production traffic. Feel free to call us if none of the offered usage tiers are accommodating for your traffic shape, and we will work together to find a solution.

Note: we don't keep your credit card on file, in a format that could be decrypted or tracked for purchases from other sites. We are using tokenizing services offered by our payment processors.

API settings

If you are looking for your customer id and your API secret key, which are both needed when sending API requests to our website, here they are. The customer id is fixed, however you can change the secret key if you need to. The obsoleted key will keep being valid for another while, unless you decide to invalidate it immediately.

You can also provide a set of IP addresses where calls to the cipherwallet API will be authorized in your name. Use classic notations, like 97.98.99.0/24 to authorize access from any IP address like 97.98.99.*, or 0.0.0.0/0 to authorize http calls from any IP address.

Checkout Services

Consider your typical checkout page on your web application. Essentially, it is a web form, asking the user to fill in credit card details, name, email, shipping address and so on. The cipherwallet checkout service is designed so that the user can scan a QR code, and auto-fill your checkout web form with data stored in their mobile device.

Start implementing your cipherwallet checkout service by defining it on your dashboard page. Check the description on the dashboard "services" section for detailed information.

When you use the cipherwallet checkout service, your web app requests an unique QR code from the API, which is displayed along with the credit card entry form. When a cipherwallet user scans the QR code with the mobile app, they are shown a screen that tells them what data items are requested, and how they will be used. Thru the settings available on the dashboard page, you are in control of what data you want to obtain, and how you present the request to your user. The user selects which data they want to send over (e.g. which credit card they want to use, what postal address they want to get the shipment to, etc), and in the end taps the "Submit" button in the cipherwallet mobile app. At that point, the data selected by the user gets transferred to your web application, and automatically fills in the fields in the web checkout form. The payment gets processed like it always did - you don't need to make any changes to your payment processor code. As an option, you can transfer the data from the user's mobile app directly to your payment processor, as soon as you obtain it, just like the user would already have pressed the "submit" button of your website's checkout form. (This is similar to the Amazon's 1-click ordering method, except that there's no actual click).

Let's get into more detail. When your checkout page displays on the user's browser, your web application makes a request for a QR code to the cipherwallet API. In the request for the QR code, your application submits:

  • your customer ID and the authentication information;
  • the service name, as you defined it in your dashboard;
  • an identifier for the session in progress (which is not the real browser session - let's call it a "cipherwallet session");
  • an URL pointing back to your website, where data from the user's mobile cipherwallet app is expected;
  • how long the QR code should be valid (e.g. 180 seconds);
  • a text to be displayed at the top of the mobile app's screen;
  • a template that contains the data items you want to collect from the user.

A sample QR request including all the variables that can be transmitted is:

POST /:service_name/:session_id HTTP/1.1
(headers)
callback_url=...&
ttl=...&
display=...&
rq_template=...
  • :service_name (required) is the name of your checkout service as you defined it in the dashboard;
  • :session_id (required) is an unique identifier for the user's session (you shouldn't use the real session ID that your server maintains, so just make up some cipherwallet session ID, associate it with the real session, and send that one over);
  • callback_url= is the URL that your website expects the user's data to be transmitted on; it should be pre-programmed in the service definition on your dashboard, but you can override that with whatever you send in your QR code request;
  • timeout= (in seconds) is the amount of time the QR code will be valid; the default is 300 (5 minutes), maximum 1200 seconds (20 minutes);
  • display= is a text to be displayed to the user; normally, the text that you have on your service definition from the dashboard page would be displayed, but it will get overridden with whatever you send here - this makes it possible to make up dynamically something to display, like "Pay $23.45 for the 3 items in your shopping cart";
  • rq_template= is the list of requested data items, in a JSON representation; normally the list of items that's been pre-programmed in the service definition would be used, but you may override that items list by explicitly sending it in your QR code request.

If everything is OK with your request, you will receive the QR code from the cipherwallet API, as a .png image, which you can immediately display on the checkout page. Alternatively, you may receive the following HTTP status values:

  • 401 if there is something wrong with the authorization of your request, or the authorization failed
  • 403 if you restricted the range of IP addresses in your dashboard, and the IP that originated the request does not pass your restriction
  • 404 if your service is not defined in the dashboard
  • 429 if you reached the maximum number of requests for your plan subscription

The URL represented with the QR code received points to a service descriptor temporarily stored on the cipherwallet API servers. When the user scans the QR code with the cipherwallet app, the app receives the description of the service (namely the things that it needs to display on the screen requesting the data). As mentioned, QR codes have a limited time-to-live. Your web application should hide the QR code once it expires, because the cipherwallet mobile app will issue an error if the service descriptor data is not available anymore.

The user selects the values they want to transmit for the requested data items, and presses "Submit". At that point, all the data collected is forwarded to your web application, on the callback URL you pre-programmed in the dashboard (or sent in the QR code request). Therefore, after obtaining the QR code image, your web application should expect at any time to receive data from the user. As such, your checkout page should be designed to poll your web server at regular intervals of time (1-2 seconds). Establishing a web socket connection is an alternative, and perhaps better, implementation.

The data transmitted from the mobile app will be delivered in a POST request with JSON content. It is made directly to your web server, and will have this format:

POST /:callback_url HTTP/1.1
(headers)
{
    "session": "...",
    "user data": { ... }
}

The "session": key will contain the same value that you used in the :session_id parameter, when you requested the QR code. The rest of the keys will be the names of the service parameters, as declared in the dashboard service definition or in the rq_template= parameter of your QR code request. Their values will be the actual data selected by the user on their cipherwallet mobile app. The structure of this data is described below.

The cipherwallet mobile app expects a response to its request, and will communicate the success or failure with a pop-up box on the mobile device. An http status code of 200 OK indicates the data transfer was successful, any other value in the 400 or 500 range would be treated as a failure. You can customize the text in the popup box by sending a JSON content like:

{
    "confirm": {
        "title": "...", 
        "message": "..."
    }
}

Typically your web application would need to temporarily store the contents of this POST request, until the next poll from the user's browser is received (which is probably less than a couple of seconds later). Your web app would normally deliver the data in the response to the poll request. With some javascript script running on the browser side, you will dispatch the data to the corresponding form fields, remove the QR code from the page, stop the polling, etc.

Signup services

If you didnt have the chance to read the chapter describing the checkout service, do it now, because the signup service is very much similar. There's just a little twist at the end of it, which is about registering the user for QR code based logins.

Signup services provided by cipherwallet help with auto-filling web forms that you provide to sign up new users of your web service. (Doh...) You define the signup service in your cipherwallet dashboard, adapt your sign up web page to display a QR code obtained from the cipherwallet API, create a polling mechanism that detects when the data arrived from the user's mobile app, and distribute this data to the appropriate fields in the web form. At one point the user will push the "Submit" button on their browser, and you would have to perform the same operations to sign them up, plus quickly confirm with the cipherwallet API that the user's sign-in was eventually accepted.

Requesting the QR code, and receiving the information from the user's device, works the same as in the checkout service. Even the API calls look the same. There is, however, one additional piece of information that the mobile device transmits to your website, along with the user's data - we call it registration metadata. The POST request you receive from the cipherwallet mobile app looks like this:

POST /:callback_url HTTP/1.1
(headers)
{
    "session": "...",
    "reg_meta": {
        "tag": "...",
        "complete_timer": ...
    },
    "user data": { ... }
}

The metadata comes in the "reg_meta": additional key. We will describe in a moment how and when the registration metadata comes in play.

Like we described for the checkout services, a poll mechanism running on the user's browser will need to collect the user data. As such, the API handler that serves the above request will need to store it for a few seconds in a short term memory, keyed with the session id. The browser knows the session id, so it should be able to retrieve the user data as response to its poll.

Note: if you find it easier, feel free to use a browser push mechanism, like web sockets, instead of the poll.

You still need to send a response to the POST request that brought over the user data. For the checkout service, we talked about some optional text values to populate a confirmation popup box in the mobile app - these are still valid. For the signup service, we use the response to transmit cipherwallet login credentials back to the mobile app.

{
    "confirm": {
        "title": "...", 
        "message": "..."
    },
    "credentials": {
        "cw_user": "...",
	      "secret": "...",
	      "hash_method": "...",
	      ...
    }
}
  • "cw_user": is an unique user identifier that you attribute to the user. The user will never actually see it, and will never have to type it, so feel free to come up with arbitrary numbers or strings - of course, as long as they uniquely identify the user.
  • "secret": is a secret hashing key, which will be used during the login process. We will present more details later, but for now keep in mind that it should be a long, cryptographically random byte string. A 64 characters digits, uppercase and lowercase letters is a appropriate for this use. This string is never displayed to the user.
  • "hash_method": is an HMAC hashing method to be used for one-way encrypting a signature string, during the login process. From the weakest to the strongest, the acceptable methods are md5, sha1, sha256 and sha512.
  • any other key-value that you add under "credentials": will be communicated back to your server with login operations requests

Your website would construct the set of credentials on the spot, while building the response to the POST request. The credentials, together with the tag received in the registration metadata, should be temporarily saved, long enough to give the user the chance to complete the registration process. Remember, so far we only helped the user to auto-fill their signup form on the screen, but the user did not finalize the process yet. If they never do, the credentials will be eventually discarded from the cipherwallet mobile app (namely, after the "complete_timer": period expires). However, if the user eventually does submit the signup form data to your server, you will have to create a permanent user record in your database. Creating an user record is no different than what you are used to do for any website that registers users; you just have to add some more data fields, to accommodate the "cw_user": value (if different from your regular user ID), the user's secret key, and the cipherwallet tag (which is an UUID).

There is one more operation needed - confirming the user registration with the cipherwallet API. This way, our servers will be aware that your user has indeed completed the signup process with your website, and will filter out any fake login requests. To register the user, a simple API request needs to be sent:

POST /reg/:tag HTTP/1.1
(headers)
(no content)
You will receive a response with no body content; the http status code will indicate:
  • 401 if there is something wrong with the authorization of your request, or the authorization failed
  • 403 if you restricted the range of IP addresses in your dashboard, and the IP that originated the request does not pass your restriction
  • 410 if the registration request came in too late (it is only available for a number of seconds indicated by the "complete_timer": key)
  • 429 if you reached the maximum number of users that your plan subscription can handle

At a later time, if necessary, you may indicate to the cipherwallet API that your user has been deregistered, by sending a DELETE request with the user's tag, and no content:

DELETE /reg/:tag HTTP/1.1
(headers)
(no content)

The cipherwallet servers will maintain your registered user records for a period of 6 months (180 days), measured since the last time the user had attempted a login to your website. If you need to maintain the record for longer than that, before the 6 months expire, you may send a HEAD request with the user's registration tag to the cipherwallet API:

HEAD /reg/:tag HTTP/1.1
(headers)
(no content)

Worth emphasizing here that none of the user's details (user ID, secret key, or personal data) are stored on the cipherwallet database. The only thing that cipherwallet stores is the anonymous registration tag we discussed about.

Login Services

A login service needs very little interaction with the mobile app user, but quite a lot of interaction with the cipherwallet server. When the user scans the QR code on the login page, the authentication data gets transmitted from the mobile device to the website; the website verifies the credentials, and grants the user access to their personalized and private services. There are no forms to fill, no options to select, no submit buttons to click - it all happens automatically.

Obviously, to be able to use the QR-based login, an user must have previously registered their device with your web application. The registration either happened at the end of a cipherwallet-enabled signup process, or after the user signed in, using the registration service. Regardless of the method, we consider that somehow the user's mobile app received and stored a set of credentials (an user ID, a secret key, a hashing method, and possibly more data), and stored them on the mobile device. The cipherwallet login service is not based on transmitting the same username and password that would be typed in the login form; instead, it works by composing a signature from a set of data items (the user id, an element of randomness, a timestamp element, and some more stuff), and then hash it with the secret key. The hashing is performed on the mobile side, and the encrypted signature, including the elements used to build it, are sent to your website. Your website will reconstruct the signature, will hash it with the user's secret key, and will compare the result with the encrypted signature coming from the cipherwallet mobile app. This way, the secret key of the authentication never travels over the wire, not even encrypted.

You start implementing the service the same way you did for the other ones: create a login service descriptor in the dashboard page, and assign the info and the callback URLs that point back to your website. The user doesn't need to manually select any private data from their mobile app (it is all picked up automatically), so there will be no display element, and no list of parameters to define and move around.

Prepare room on your login page to display the QR code image, and obtain this image by calling the cipherwallet API:

POST /:service_name/:session_id HTTP/1.1
(headers)
ttl=...
  • :service_name is the name of the login service you are initiating (you may have more than one login page)
  • :session_id is an unique browser session identifier, so that you can later match the authentication data received from the mobile app with the web client that presented the QR image. Although you could, you should not use the same session ID as the one that your server typically sets in the cookies. Just create a different, random one, and associate it internally with the session in progress.
  • ttl= indicates a time-to-live for the QR code (default is 120 seconds, and maximum is 1200 seconds).
Note: as an enhanced spoof protection, you may not override the callback URL for the login service.

Prepare a javascript that runs in your login page and polls your server, to determine when / if the data from the user's mobile app has become available. When the user scans the QR code, the cipherwallet mobile app determines which service, on which website, the code refers to. It selects the appropriate set of login credentials from the mobile app keychain:

  • the cipherwallet user id
  • the hashing method
  • the current UTC timestamp
  • a random nonce
  • possibly more data, received during the registration process

The above data items are sent in clear. They are also used to create a canonical signature (we will describe later, in more detail, the recipe used for creating the signature). This signature, and the secret key, will be hashed using an HMAC algorithm, and transmitted in a first hop to the cipherwallet API. As you can see, the secret key is not part of the communication itself.

The cipherwallet API verifies that the mobile app was indeed registered with the website that offered the login opportunity. If the registration is valid, the cipherwallet server calls your web application on the callback URL that you programmed to receive the login credentials. The call includes all the user data, unaltered, plus the session information transmitted by your website when the QR image was requested. (In fact, for additional protection, the session information is never communicated to the mobile app - we want to keep it isolated from a potential attacker.) To make sure your website gets indeed called by the cipherwallet API, the cipherwallet server signs its request with your own API secret key. Here is how the request to your callback URL looks like:

POST /:callback_url HTTP/1.1
X-Client-Id: api.cqr.io
X-Timestamp: ...
X-Nonce: ...
X-Hash-Method: ...
Authorization: CQR 1.0 ...
(more headers)

session=...&
cw_user=...&
(possibly more parameters)
nonce=...&
timestamp=...&
hash_method=...&
authorization=...

It may seem a little confusing that the cipherwallet server transmits the same data twice - in the headers, and in the request body. But you have to consider that, in fact, you need to do 2 authorizations:

  • one of them is made up with the values of the extension headers (that start with X-), and the Autorization: header; this is the cipherwallet server authorization - you need to make sure that the data comes indeed from where you expected to come.
  • the second authorization is the actual user authorization, and is constructed with the values of the POST parameters; validating this authorization means that the user's cipherwallet application knows both the username and the shared secret key assigned to them.

We will describe the actual recipe for the authorization in a later chapter.

In terms of processing, when the callback POST request is received, your web app:

  1. Follows the procedure of authenticating the http request, using the extension tags in the request (Note that X-Client-Id: is set to api.cqr.io)
  2. Makes sure that the browser session is still in progress
  3. Temporarily saves the user's credentials until the next poll request is received from the browser

The cipherwallet server expects a response with a 200 OK http status, or any appropriate 400 or 500 http status if something was wrong so far. The status is relayed to the cipherwallet mobile app. At this stage, your website doesn't yet know if the user can be authorized or not - the user authorization only happens when the next poll is received. The web app can add content that would display on the cipherwallet mobile application, that would be particular to that user (for example, the date of the last order, or the total of the user's last 3 transactions). This "certificate" could offer confidence to the user that their login information got transmitted to your website, and not to a malicious imitation website.

Note: This implementation would not communicate the success or failure of the login operation to the cipherwallet servers. You could, probably, authorize the user on the spot and transmit the success or failure information to the cipherwallet app, but that would mean that the cipherwallet servers would know that bit of information as well. Not that they would use it in some malicious way, but it would be against the "zero knowledge" mantra of cipherwallet.

On the next poll request received from the browser for the corresponding session, your web app performs the actual user verification:

  1. It retrieves the login data associated with the session;
  2. Builds the signature using the same recipe as the cipherwallet mobile app;
  3. Hashes the signature, using the user's secret key found in your database;
  4. Compares the hash result with the authorization= parameter received.

If everything matches, it means that your website can consider the user as authenticated for the web browser session, and can safely execute the same operations that a normal, username-and-password login would trigger on success. That usually involves setting server-side session variables, and redirecting the user's browser to the page where an user would land after a login.

For enhanced security, it is desirable that the website take some additional measures. For example, the QR code image should be removed from the page when the time-to-live expires (it wouldn't be useful anymore anyway). Also, receiving a set of invalid login credentials should invalidate the currently displayed QR code, and instruct the user to refresh the page to obtain a new code.

Registration Services

To use the cipherwallet QR-based login service, an user must first register. The user registration is typically preformed as an additional feature of the signup service. This separate registration service is offered to cover various other situations:

  • accommodate the users you already have at the time you start using cipherwallet logins
  • register users that installed the cipherwallet mobile app only after they signed up
  • change credentials of already registered users, if your security policy requires it

The end result of a successful user registration process is to have a set of credentials, unique to the user, stored in both your website's database, and in the user's mobile app local storage. In addition to this, the cipherwallet API servers will maintain a record that associates the user's mobile application instance with your website. Later on, you may use the identifier of this record (which is what we called before "the registration tag") to tell the cipherwallet servers that you cancelled that user's registration.

Begin by creating a registration service on your cipherwallet dashboard page. You only need to indicate the callback URL exposed by your website. Similar to the login service, the registration service doesnt need to show an UI on the mobile app, so you don't need texts to display or parameters to select.

The registration QR code needs to be displayed on a page that is only accessible after the user logged in. Typical placement is on the user's account management page, around the same area where the password can be changed. The web app would obtain the QR code from the cipherwallet API with a typical request:

POST /:service_name/:session_id HTTP/1.1
(headers)
ttl=...
Note: The time-to-live should be shortened as much as possible, to prevent malicious devices attempting to obtain a set of credentials for the logged-in username. The default, and the maximum value is 30 seconds.

Prepare a javascript function that runs in your registration page and polls your web server, to determine when / if the data from the user's mobile app has become available. When the user scans the QR code, the mobile app is redirected to the callback URL you selected in the dashboard. So your website receives a POST request with JSON content, directly from the user's mobile app:

POST /:callback_url HTTP/1.1
(headers)
{
    "session": "...",
    "reg_meta": {
        "tag": "...",
        "complete_timer": ...
    }
}
Note: The callback for the registration service MUST use an https connection.

Note that the format is identical to the callback from a signup service, less the user data. Before responding to the mobile app, your web app should first inform the cipherwallet API that it will register the user, using the "tag:" value from the request. It does that with a POST request:

POST /reg/:tag HTTP/1.1
(headers)
(no content)

Yup, it's the same registration tag confirmation that we used in the signup service. On success, the cipherwallet API responds with a 200 OK (and no content). If this happens, your web application can generate a 200 OK response that contains a set of user credentials, which include (at least):

  • the user ID (the unique user identifier from your database, or one you generate and associate with the user)
  • a secret key that the mobile app will use in performing the QR-based login services, to hash a signature; use a string generated by a cryptographically grade randomizing algorithm
  • the hashing algorithm to use on login attempts (from the weakest to the strongest, it can be md5, sha1, sha256 or sha512).

You can add additional keys, that will be transmitted as parameters in every future login attempt (they can only be scalar values though, like numbers or strings). A response content will, again, look like the one for the signup service, except for the dialog artifacts:

{
    "credentials": {
        "cw_user": "...",
	      "secret": "...",
	      "hash_method": "...",
	      ...
    }
}

The mobile app will store the credentials on its storage device and... that's it! will be ready for the next user's login.

Authentication

Each request you send to the cipherwallet API must be authenticated, so that the server can properly and uniquely identify you as a customer. The cipherwallet API uses a simplified form of the OAuth 1.0 algorithm. The authentication consists in creating a signature string, which is then hashed with a secret API key. The parameters composing the signature are sent in clear, therefore the cipherwallet API can re-create the signature on their end; if the result of hashing the signature string with the secret key is the same as the one received in the request, the API authorizes the execution of the http request.

The parameters involved in creating the signature are:

  • the type of request (GET, POST, PUT, DELETE) and the resource
  • a few custom request headers: X-Client-Id, X-Timestamp, X-Nonce, X-Hash-Method
  • the parameters of the request, and their values

The signature string is a sequence of text lines, separated by CR (\n, or ASCII 0x0A). Here is the recipe for building the signature string:

  1. The first line is composed by the type of request (GET, POST, PUT, DELETE), in uppercase; a space character (0x20); and the resource string. The resource string is the part of the request URL that starts after the domain name, and ends at the end of the URL. If query parameters are present in the URL string, like in GET requests, the resource string ends with the character right before the question mark separator. For example, if the request is a GET:
    https://api.example.com/some/useful/resource?param=value&foo=bar
    the first line of the signature is:
    GET /some/useful/resource
  2. The next lines contain the custom headers, one per line. The format of each line is: header name; a column character (0x3A); and header value.
    X-Custom-Header:the_header_value
    The names and values of the custom headers are case sensitive. The custom headers name-value pairs must be inserted in the signature string in the following order: X-Client-Id, X-Timestamp, X-Nonce, X-Hash-Method.
    • The X-Client-Id header must contain your customer id (see the 'API settings' area on your dashboard page). Cipherwallet uses UUIDs as customer IDs.
    • The value for X-Timestamp is the current timestamp, in epoch or unix time format (the number of seconds since midnight January 1st, 1970, GMT).
    • The value of X-Nonce is a random string, generated at each request. The value should not repeat over a 60 minutes time interval. You may safely use an UUID generator as a source.
    • Finally, X-Hash-Method contains the HMAC algorithm used to hash the signature; can be one of md5, sha1, sha256, sha512.
    Here is an example of the headers part of the signature:
    X-Client-Id:db07ac00-b6b3-45e8-a030-cb8c8b76b192
    X-Timestamp:1343272485
    X-Nonce:aa466520-d6cf-11e1-9b23-0800200c9a66
    X-Hash-Method:sha256
    
  3. The rest of the lines contain the request parameters and their values. There is one name-value pair per line. The parameter name and value are separated by an "equals" = sign (0x3D). The value should NOT be prefixed or terminated with space or tab characters. For signature building purposes, all the parameter names are converted to lowercase. The parameter name-value pairs are added to the signature in the sorted order of the (lowercase) parameter names.
    The full signature for the GET request exemplified earlier in step 1 looks like this:
    GET /some/useful/resource
    X-Client-Id:db07ac00-b6b3-45e8-a030-cb8c8b76b192
    X-Timestamp:1343272485
    X-Nonce:aa466520-d6cf-11e1-9b23-0800200c9a66
    X-Hash-Method:sha256
    foo=bar
    param=value
    
  4. This signature string is then hashed with the hmac algorithm selected in the X-Hash-Method header - in our case, sha256, using the API secret key as hashing key. Since the result is a bytes array, apply a base64 encoder to obtain an ASCII string. Then, set the Authorization: header of your request to the string CQR 1.0 and append a space character (0x20) and then the hashed-base64-encoded signature. It’s gonna look like this:
    Authorization: CQR 1.0 HRJkzp8HQ+x4MU4ah4/FsLYatk4y9BfOdBXNw5bnNxE=

The string used as encryption key to generate this example is:

1234567890123456789012345678901234567890123456789012345678901234

but obviously, you would need to use the secret key provided on your dashboard page.

If you need a simple way to verify your authentication function, and encryption procedures, you may use the /ping facility of the cipherwallet API, which responds to GET and POST requests. You may send any request parameters you like. Other than confirming that our system is alive and healthy, you will obtain a copy of the signature string that the API reconstructed from your request, before encrypting it with your secret API key. In other words, the /ping APIs return the signature as expected from your application, before you hashed it.

User Authorization

The login service sends user authentication data from the mobile device to your website, relayed thru the cipherwallet server. The authentication mechanism is similar to the one used by the cipherwallet API server when authenticating requests, except that the signature is built with the parameters in the POST request, instead of the headers. As detailed in the login service description, the body of the POST request contains the following parameters:

  • session= the unique identifier for the browser session that needs to log in
  • cw_user= would be the user unique identifier (you may have called it differently, during the registration procedure)
  • nonce= a randomly generated nonce
  • timestamp= the timestamp, in epoch format (number of seconds since January 1st, 1970)
  • hash_method= the HMAC method used for hashing the signature
  • authorization= the encrypted (hashed) signature, in base64 format
Note: more parameters may be transmitted in the login request - depending on what you programmed in the user credentials, at signup or registration time. All of the parameters will be entered in the computation of the signature.

To compose the signature:

  1. Validate the existence and the values of the parameters you expect (for example, the same nonce should not have been used in the last few hours, timestamp should not be drifted more than a few minutes, etc.)
  2. Convert all the parameter names (and names only - not values) to lowercase
  3. Arrange the lowercase parameter names in alphabetical order; do NOT include the authorization= parameter in this sorted list
  4. For each parameter in the sorted list, create a line composed of the parameter name, converted to lowercase; the "equals" = sign (0x3D); and the parameter value
  5. Concatenate the lines obtained as above, separating them by a newline character (0x0A); this is the raw, unencrypted signature.
  6. Encrypt the signature with the HMAC algorithm indicated by the hash_method= parameter, applying the user's secret key that you looked up in your database, based on the value of the cw_user= parameter
  7. Encode base-64 the encrypted signature
  8. Replace all "plus" + (0x2B) characters from the encrypted and base-64 encoded signature, with "period" . (0x2E)
  9. Compare the result with the value of the authorization= parameter; if they match, your user knows the same secret key that you would expect them to know, and they can be considered authenticated.

User Data

For the checkout and signup services, the expected result is that the mobile cipherwallet application will transmit, with a callback POST request to your website, some personal user data that you require, and the user agrees to send. The data gets transmitted directly to your server; the cipherwallet servers would not get to see the user data, not even encrypted. Also, the user will always be in control of what data items, and what data content, gets sent, and to which website.

As described before, you start by defining the cipherwallet checkout or signup services on the dashboard page. You select and make sure you have a functional callback URL. You also prepare a message to be displayed to the user, to let them know what you plan to do with their data, and to increase their confidence that they send the data in the right place. And then, you will have to prepare the data items that you need from them.

Each data item is defined by a parameter, which has:

  • a name: a programatic name for the data item that gets collected and sent to your web service;
  • a type: what kind of data this parameter holds;
  • a label: a short description about how this parameter will be used; the label is shown on the mobile app data selection screen (for example, "Select shipping address");
  • whether you consider the parameter optional or not (e.g. you can ask the user for their phone number on the signup page, but you don't want to reject the signup if the user doesn't want to disclose it).

By programming a parameter with a specific type, you would actually ask the user to provide you with a matching piece of personal information. You would expect to receive a value for that parameter, with the name that you defined. For example, if you need to ask for the user's credit card, you would add a parameter that has the name cc, the type set to credit card, would (probably) not make it optional, and label it as Select a credit card. On the mobile app data selection screen, the field would be displayed like this:

The user can scroll left and right thru their credit cards, and pick the one that they want to use for the transaction. When the data gets sent to your web app, for this particular data item you would receive a specific key "cc": (this is the name that you chose for the parameter), with subfields that contain credit card information (number, expiration date, etc).

Here are the types of parameters supported by cipherwallet, the subitems that get reported:

  • name: "first":, "last":
  • birthday: "birthdate": (format is like January 1, 1970)
  • gender: "gender": (male or female)
  • photo: "photo": (the image format is PNG, and the binary content is base64 encoded)
  • email address: "email":
  • phone number: "phone":, "cansms":
  • credit card: "type": (AmEx, VISA etc), "num":, "name":, "exp": (format is MMYY), "cvv": (3 or 4 digits), "zip":, "scanned": (boolean)
  • mailing address: "street":, "street2":, "city":, "state": (2 characters), "zip":
  • workplace: "company":, "website":, "position":
  • location: "lat": (degrees and decimals), "long": (degrees and decimals), "accuracy": (in meters)
  • area: "lat":, "long":, "accuracy":
Note: "location": will always return the most accurate location of the mobile device, available when the data is submitted. "area": will return a random coordinate, less than 5000 meters away from the actual location, so the accuracy will never be less than 5000m.

Consider this example of parameters list:

Here is how the contents of the callback URL will look like:

{
    "session": 98765432,
    "user_data": {
        "name": { "first": "Jane", "last": "Doe" },
        "phone": { "phone": "8185551212" },
        "email": { "email": "jane.doe@gmail.com" },
        "creditcard": { 
            "type": "AmEx", "num": "378282246310005", "exp": "1214", "cvv": "1234", 
            "name": "Jane Doe", "zip": "91999", "scanned": true 
        },
        "billto": { 
            "street1": "5555 W Cipherwallet Blvd", "street2": "", 
            "city": "Nowhere", "state": "CA", "zip": "91999" 
        }
    },
    "approx_location": { "lat": 37.067014, "long": -95.616916, "accuracy": 5425. },
}

A few things to note in the example above:

  • When you ask for an item, all its constituent subitems get sent; you just need to interpret what you need.
  • The user may not have filled all the data subitems (e.g. there is no second line for street address). This item data will be reported as an empty string.
  • For the parameters marked as optional, the user may decide not to send data. In this case, the key corresponding to the parameter will be missing from the JSON document (see the missing "shipto": key above).
  • Multiple parameters with the same type (like) mailing address in the example) are used on the form. The parameter names name, not their types, makes them distinctive.

DATES THIS DOCUMENTS WAS MODIFIED

Dec 11, 2014

document created