Zenfolio API Authentication

The other day I decided that I would add Zenfolio support to my photo tagging site, smark.us.  (I’m sill working on that, btw.) However, I was unable to find any Zenfolio Python libraries, so i wrote one.  Since Zenfolio supports JSON-RPC, it was quite easy, however I found their authentication documentation to be a little vague on how to generate a valid response to a provided challenge.  After poking at it for a bit, I got it working.  To help other folks save time, here is a code snippet that you can use to generate a valid response to a challenge issued by GetChallenge().  Note that this is only for JSON-RPC.  Other protocols such as SOAP use different encodings.

def GenerateAuthenticateProof(auth_challenge, password):
  """Generate proof for calling Zenfolio's Authenticate() method via JSON-RPC.

  Args:
    auth_challenge: Dict like object containing the result of a call to Zenfolio's
      GetChallenge().  It must contain key values PasswordSalt and Challenge.
      Both of which should represent lists of integers.
    password: User password as a string

  Returns:
    A list of integer values that should be serialized and passed as the proof
    argument when calling Zenfolio's Authenticate method."""

  # Convert the numeric salt and challenge arrays into binary strings.
  salt = ''.join([chr(x) for x in auth_challenge['PasswordSalt']])
  challenge = ''.join([chr(x) for x in auth_challenge['Challenge']])

  # Calculate a hash of the binary salt and the password as utf-8
  combo = salt + password.encode('utf-8')
  h2 = hashlib.sha256(combo)

  # Calculate the proof digest
  combo = challenge + h2.digest()
  h1 = hashlib.sha256(combo)
  proof = h1.digest()

  # Return the proof digest as a list of integer values.
  return list(struct.unpack('B'*32, proof))
Share this:
  • Digg
  • Twitter
  • del.icio.us
  • Google Bookmarks
  • Reddit
  • Slashdot
  • Suggest to Techmeme via Twitter
  • Identi.ca
  • Ping.fm
  • Technorati
blog comments powered by Disqus