Token Generation

mgp25 edited this page Mar 28, 2016 · 7 revisions

What is the token used for?

The token is used to request the code to register the number.

Android

How is generated?

function generateRequestToken($country, $phone) {

  $waPrefix     = "Y29tLndoYXRzYXBw";
  $signature    = "MIIDMjCCAvCgAwIBAgIETCU2pDALBgcqhkjOOAQDBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC1NhbnRhIENsYXJhMRYwFAYDVQQKEw1XaGF0c0FwcCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEUMBIGA1UEAxMLQnJpYW4gQWN0b24wHhcNMTAwNjI1MjMwNzE2WhcNNDQwMjE1MjMwNzE2WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExFjAUBgNVBAoTDVdoYXRzQXBwIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5nMRQwEgYDVQQDEwtCcmlhbiBBY3RvbjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDRGYtLgWh7zyRtQainJfCpiaUbzjJuhMgo4fVWZIvXHaSHBU1t5w//S0lDK2hiqkj8KpMWGywVov9eZxZy37V26dEqr/c2m5qZ0E+ynSu7sqUD7kGx/zeIcGT0H+KAVgkGNQCo5Uc0koLRWYHNtYoIvt5R3X6YZylbPftF/8ayWTALBgcqhkjOOAQDBQADLwAwLAIUAKYCp0d6z4QQdyN74JDfQ2WCyi8CFDUM4CaNB+ceVXdKtOrNTQcc0e+t";
  $classesMd5   = "ZXEimx8U9X1WZwQmVJRnGA=="; // 2.11.481
  $k            = "PkTwKSZqUfAUyR0rPQ8hYJ0wNsQQ3dW1+3SCnyTXIfEAxxS75FwkDf47wNv/c8pP3p0GXKR6OOQmhyERwx74fw1RYSU10I4r1gyBVDbRJ40pidjM41G1I1oN";
  $KEY          = "The piano has been drinking";


  // We xor this file because I don't want to have a copyrighted png 
  // on my repository
  $f =  file_get_contents("magic.dat");
  $count = 0;
  for ($i=0; $i < strlen($f); $i++) {
          $f[$i] = $f[$i] ^ $KEY[$count++];
          if ($count == strlen($KEY) -1) {
                  $count = 0;
          }
  }

  $d = base64_decode($waPrefix) . $f;
  $key2 = pbkdf2('sha1', $d, base64_decode($k), 128, 80, true);

  $data = base64_decode($signature) . base64_decode($classesMd5) . $phone;

  $opad = str_repeat(chr(0x5C), 64);
  $ipad = str_repeat(chr(0x36), 64);
  for ($i = 0; $i < 64; $i++) {
    $opad[$i] = $opad[$i] ^ $key2[$i];
    $ipad[$i] = $ipad[$i] ^ $key2[$i];
  }

  $output = hash("sha1", $opad . hash("sha1", $ipad . $data, true), true);
    
  return base64_encode($output);
}

We use a precalculated $key2 = base64_decode('eQV5aq/Cg63Gsq1sshN9T3gh+UUp0wIw0xgHYT1bnCjEqOJQKCRrWxdAe2yvsDeCJL+Y4G3PRD2HUF7oUgiGo8vGlNJOaux26k+A2F3hj8A=');

The magic.dat is a xored image. We have done that in order to avoid having a copyrighted image. You can find this image inside of the APK.

  • $KEY is the key to decrypt the xored image.
  • $k and $waPrefix are strings stored inside in the APK.
  • $signature it's the signature.
  • $classesMd5 it's the raw md5 of classes.dex base64 encoded.

Obtaining classesMD5

$classesMD5 = base64_encode(md5_file($classesFile,TRUE));

You can also use this utility classesMD5-64

In the WhatsAPI-Official code, we use the precalculated key so it take less time.

S40

$timestamp = "1418865329241";
$token = md5("PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk".$timestamp.$phone);
  • PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk its a constant, never changes.
  • $timestamp it's the release time of the app, it's inside the app. Changes in every version.
  • $phone, your number + country code.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.