Skip to content
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.
Clone this wiki locally