Cristian Garcia
Cristian Garcia

Reputation: 9859

Base64 HMAC-SHA1 and MD5 encryption in Dart and Vuforia's VWS API

To communicate with Vuforia through its VWS API I have to do some tricky stuff: first create this string

StringToSign = 
  HTTP-Verb + "\n" +
  Content-MD5 + "\n" +
  Content-Type + "\n" +
  Date + "\n" +
  Request-Path;

where Content-MD5 is the encryption of the request's body...

(from the first boundary to the last one, including the boundary itself). For request types without request body, include the MD5 hash of an empty string which is “d41d8cd98f00b204e9800998ecf8427e”.

then with this string you have to perform the equivalent to this Java code

Signature = Base64 (HMAC-SHA1 (server_secret_key, StringToSign));

where server_secret_key is a constant. Finally you have to plug that into an authorization header of this form

Authorization: VWS {provision_access_key}:{Signature}

I've got no experience with encryption, can anybody tell me how to do this in Dart?

Edit

More info about this on Setting Up the API

Upvotes: 2

Views: 3332

Answers (1)

sgjesse
sgjesse

Reputation: 4628

All the algorithms you need for this are in the dart crypto package.

import 'dart:convert';
import 'dart:io';

import 'package:crypto/crypto.dart' as crypto;

main() {
  var contentStr = '{x:"y"}';
  var content = UTF8.encode(contentStr);
  var md5 = new crypto.MD5();
  md5.add(content);

  var verb = 'GET';
  var hash = crypto.CryptoUtils.bytesToHex(md5.close());
  var type = 'text/plain';
  var date = HttpDate.format(new DateTime.now());
  var path = '/request/path';
  var stringToSign = '$verb\n$hash\n$type\n$date\n$path';
  print(stringToSign);
  print('');

  var keyStr = "0102030405060708090a0b0c0d0e0f";
  var key = [];
  for (int i = 0; i < keyStr.length; i += 2) {
    key.add(int.parse(keyStr.substring(i, i + 2), radix: 16));
  }
  var hmac = new crypto.HMAC(new crypto.SHA1(), key);
  hmac.add(UTF8.encode(stringToSign));
  print(crypto.CryptoUtils.bytesToHex(hmac.close()));
}

Of cause you need to figure out the exact encoding of the different parts, e.g. the date. If just one bit is wrong in the input nothing works.

If you have some examples of input and output it is much easier to get the details right. E.g. test the MD5 of the empty string

print(crypto.CryptoUtils.bytesToHex(new crypto.MD5().close()));

Upvotes: 5

Related Questions