Browser-compatible implementation of HPKA.
Loosely based on node-hpka.
NOTE: For Ed25519 signatures only!
This library is dependent on libsodium. You need to include a wrapped and emscripten compiled version of it.
Prerequisites:
- GNU Build System (that contains
automake
andlibtool
, necessary to compile libsodium) - emscripten (necessary to compile libsodium to javascript)
- nodejs or io.js (necessary to build the dynamic wrapper for the js build and run tests)
Here's how you should do it:
Once you've got the cloned this repo and installed the dependencies, run
make
That will build libsodium to javascript and build its wrapper sodium.js
. The files you'd need to import to your app will be located in a out
folder once the process is finished.
Most functions involving "heavy cryptographic calculations" (e.g. : Ed25519 signatures and Scrypt key derviations) can be used asynchronously, but can still be used synchronously.
The library loads in a variable called hpka
. It exposes the following methods:
hpka.supportedAlgorithms()
: Returns a list containing the list of supported algorithms for the identity key. Currently, it only returns['ed25519']
hpka.createIdentityKey([Buffer|String password], [Function scryptProvider], [Function callback])
: Create an Ed25519 identity key.String|Buffer password
: Optional. A password used to protected the key (for persistent storage)Function scryptProvider
: Optional. A function that will perform a Scrypt key derivation and then return it through a callback. Receives ([password, salt, opsLimit, r, p, keyLength], cb), where cb is the callback function that receives (err, derivedKey)Function callback
: Optional. A function that will receive the result of thecreateIdentityKey
call. Usingcallback
is mandatory ifscryptProvider
is provided. Received parameters : (err, identityKeyBuffer|encryptedIdentityKeyBuffer)- returns an (optionally encrypted) Uint8Array buffer containing the generated key pair
hpka.scryptEncrypt(Buffer data, Buffer|String password, [Function scryptProvider], [Function callback])
: Encrypt the provideddata
with the providedpassword
and returns the ciphertext. Uses scrypt for key derivation, XSalsa20 as cipher and the Poly1305 MACBuffer data
: the data to be encryptedBuffer|String password
: the password to be derived and used for encryptionFunction scryptProvider
: Optional. A function that will perform a Scrypt key derivation and then return it through a callback. Receives ([password, salt, opsLimit, r, p, keyLength], cb), where cb is the callback function that receives (err, derivedKey)Function callback
: Optional. A function that will receive the result of thescryptEncrypt
call. Usingcallback
is mandatory ifscryptProvider
is provided. Received parameters : (err, cipherText)- returns the cipherText (as Uint8Array)
hpka.scryptDecrypt(Buffer|String cipher, Buffer|String password, [Function scryptProvider], [Function callback])
: Decrypt the data encrypted by thescryptEncrypt
methodBuffer|String cipher
: The data to be decrypted. If the provided data is a string, it must be hex encoded.Buffer|String password
: The password that was used on encryptionFunction scryptProvider
: Optional. A function that will perform a Scrypt key derivation and then return it through a callback. Receives ([password, salt, opsLimit, r, p, keyLength], cb), where cb is the callback function that receives (err, derivedKey)Function callback
: Optional. A function that will receive the result of thescryptDecrypt
call. Usingcallback
is mandatory ifscryptProvider
is provided. Received parameters : (err, plaintext)- returns the plaintext (as Uint8Array)
hpka.loadKey(Buffer|String keyBuffer, [Buffer|String password], [String resultEncoding], [Function scryptProvider], [Function callback])
: Returns an{keyType, publicKey, privateKey}
object, where the keys are either Uint8Arrays or strings encoded inresultEncoding
hpka.saveKey(Object keyPair, [String|Buffer password], [Function scryptProvider], [Function callback])
hpka.buildPayload(Object keyPair, String username, Number userAction, String httpMethod, String hostAndPath)
hpka.buildSessionPayload(String username, String|Uint8Array sessionId)
hpka.Client(String username, Buffer keyBuffer, [Buffer|String password])
: Constructor method for an easy to use HPKA client- String username : the username to be used for the account
- Buffer keyBuffer : the buffer containing the encoded keypair to be used with this client. KeyBuffer can also be a KeyPair object (resulting form a
hpka.loadKey
call) - [Buffer|String password] : Optional. The password to be used to decrypt the keyBuffer. To be used only if the keyBuffer you provided is encrypted
reqOptions
parameter in therequest
,registerAccount
anddeleteAccount
methods is an object that contains all the parameters needed to make a request. See below for the list of supported attributes and valueshpka.Client.request(reqOptions, callback(err, statusCode, body, headers))
: Make an HPKA authenticated requesthpka.Client.registerAccount(reqOptions, callback(err, statusCode, body, headers))
: Make an HPKA account/user creation requesthpka.Client.deleteAccount(reqOptions, callback(err, statusCode, body, headers))
: Make an HPKA user deletion requesthpka.Client.setHttpAgent(agent)
: Replace the default HTTP agent by one you specify. It should be a function taking the following parameters : reqOptions, callback; where callback will be a function receiving (err, statusCode, responseBody, headers). Example usage : using HPKA in conjunction with an https client with certificate pinning in Cordova/Phonegaphpka.Client.loadKey(Buffer|String keyBuffer, [Buffer|String password])
: Load a keypair into the Clienthpka.Client.keyLoaded()
: Returns whether the client has a keypair loaded in ithpka.Client.setKeyTtl(Number ttlMilleseconds)
: Set a TTL (time-to-live) for the loaded key, after which it will be unreferenced. Note that the TTL is in millisecondshpka.Client.resetKeyTtl(ttl)
: Restart the TTL counter with the current value or with the newttl
valuehpka.Client.clearKeyTtl()
: Disable the set TTLhpka.Client.hasKeyTtl()
: Get whether the client has a TTL set or nothpka.Client.setSignatureProvider(Function sigProvider)
: Set the Ed25519 provider for this Client instance; a function that will perform the signature and then return it through a callback. ThatsigProvider
function receives (message, privateKey, callback), where callback receives (err, signature)hpka.Client.setScryptProvider(Function scProvider)
: Set the Scrypt provider for this Client instance; a function that will perform the key derivation and then return the result through a callback. ThatscProvider
receives ([password, salt, opsLimit, r, p, keyLength], cb), where cb is the callback function that receives (err, derivedKey)
hpka.defaultAgent(reqOptions, callback(err, statusCode, body, headers))
: The default HTTP (AJAX) agent used in theClient
object.
Here are the list of attributes taken in the reqOptions
object:
- String host : the hostname to which you want to connect
- String path : the path of your request. Must start with a
/
- String method : the HTTP method you want to use. Valid values are:
get
,post
,put
,delete
,head
,patch
,trace
,options
,connect
- [Number port] : The port number you want to use. Optional parameter. Defaults to 443 (the port for HTTPS)
- [String protocol] : The protocol you want to use. Optional parameter. Must either be 'http' or 'https'. Defaults to 'https'
- [Object headers] : The headers you want to include in your requests. Optional parameter
- [String|Object body] : The request body you want to include. Optional parameter
From the repo's root folder, run:
make test
This will build the test server's dependencies (if not been previously built) and then launch it. Make sure that the dependencies listed above are installed on your computer. It will then run various test cases in a testing page loaded into phantomjs
This library is distributed under the MIT license.