This is an example of how to derive the authentication key using Python. Authentication is required where you connect to the system over IP. This is not required for serial connections.
#!/usr/bin/python
# Copyright (c) StarLeaf Ltd. 2015
import hashlib
import hmac
import pbkdf2
import binascii
def endpoint_api_key(password, salt_hex, iterations, verbose=False):
if verbose:
print "Key is PBKDF2(HMAC-SHA256, '%s', '%s', %d, 32)." % (password, salt_hex, iterations)
salt = binascii.unhexlify(salt_hex)
key = pbkdf2.PBKDF2(passphrase=password, salt=salt, iterations=iterations,
digestmodule=hashlib.sha256, macmodule=hmac)
key_hex = key.hexread(32)
if verbose:
print "Key is '%s'." % key_hex
return key_hex
def endpoint_api_response(key, challenge, verbose=False):
if verbose:
print "Response is HMAC-SHA256('%s', '%s')." % (key, challenge)
key_bytes = binascii.unhexlify(key)
hash = hmac.new(key_bytes, challenge, hashlib.sha256)
response = hash.hexdigest()
if verbose:
print "Response is '%s'." % response
return response
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option("--password", dest='password', help="API password, as set in portal.")
parser.add_option("--salt", dest='salt', help="Salt to apply to the password during key derivation.")
parser.add_option("--iterations", dest='iterations', type='int', help="Number of iterations to hash during key derivation.")
parser.add_option("--key", dest='key', help="Key derived from password.")
parser.add_option("--challenge", dest='challenge', help="Challenge returned by server.")
parser.add_option("--mode", type='choice', choices=['key', 'respond'], dest='mode', default='respond',
help="Mode: key (derive key from password) or respond (build response to challenge).")
parser.add_option("--format", type='choice', choices=['text', 'query', 'json'], dest='format', default='text',
help="Output format for response: (text (plain text), query (HTTP URI query format) or json (JSON object)).")
parser.add_option("--verbose", action='store_true', dest='verbose', help="Print details of intermediate steps.")
(opt, args) = parser.parse_args()
if opt.key:
key = opt.key
else:
key = endpoint_api_key(opt.password, opt.salt, opt.iterations, opt.verbose)
if opt.mode == 'key':
print key
elif opt.mode == 'respond':
response = endpoint_api_response(key, opt.challenge, opt.verbose)
if opt.format == 'query':
print "challenge=%s&response=%s" % (opt.challenge, response)
elif opt.format == 'json':
print "{\n \"challenge\": \"%s\",\n \"response\": \"%s\"\n}" % (opt.challenge, response)
else:
print opt.response
else:
print "Invalid mode '%s'." % opt.mode