Using CGI to generate license

Post here any topics that related to Enigma Protector, its functionality, your misunderstanding, offers to improvements etc etc etc
Post Reply
elore
Posts: 25
Joined: Sat Oct 23, 2010 4:27 pm

Using CGI to generate license

Post by elore »

Question. If I use integration with Plimus by using CGI to generate licenses how to make sure that the HTTP request is really coming from Plimus. It means that if someone will somehow once get the traffic between my site and Plimus he will be able to generate the licences by himself.

Like this:

<html><body>
<a href="http://yoursite.com/cgi-bin/keygen?Acti ... Z9D">Click here to generate registration key</a>
</body></html>

What is the most secure way to avoid this?
Enigma
Site Admin
Posts: 2945
Joined: Wed Aug 20, 2008 2:24 pm

Re: Using CGI to generate license

Post by Enigma »

Hi,

There are two ways how this can be implemented:
1. Allowing access to keygen by requester IP. Very simple and very useful. Usually, any registrars like a Plimus use special service with special IP adderss (or set of IP addresses), you may block access to keys generators just by IP. You may put keygen to particular folder and create .htaccess file there with the following text:

Code: Select all

order deny,allow
deny from all
allow from 111.111.111.111
allow from 222.222.222.222
allow from 000.000.000.000
111.111.111.111 222.222.222.222 000.000.000.000 - those are IPs of Plumis service. You have to ask their support to get full list of IP addresses that are using for keys generating.
2. Another way, if you are worry that HTTP traffic can be somehow hooked, you may use PHP POST keygen, there is a sources:

Code: Select all

<?php

  if (!function_exists('http_build_query')) {
      function http_build_query($data, $prefix='', $sep='', $key='') {
          $ret = array();
          foreach ((array)$data as $k => $v) {
              if (is_int($k) && $prefix != null) {
                  $k = urlencode($prefix . $k);
              }
              if ((!empty($key)) || ($key === 0))  $k = $key.'['.urlencode($k).']';
              if (is_array($v) || is_object($v)) {
                  array_push($ret, http_build_query($v, '', $sep, $k));
              } else {
                  array_push($ret, $k.'='.urlencode($v));
              }
          }
          if (empty($sep)) $sep = ini_get('arg_separator.output');
          return implode($sep, $ret);
      }// http_build_query
  }//if

  function do_post_request($url, $data, $optional_headers = null)
  {
   $params = array('http' => array(
                'method' => 'POST',
                'content' => $data
             ));
   if ($optional_headers !== null) {
      $params['http']['header'] = $optional_headers;
   }
   $ctx = stream_context_create($params);
   $fp = @fopen($url, 'rb', false, $ctx);
   if (!$fp) {
      throw new Exception("Problem with $url, $php_errormsg");
   }
   $response = @stream_get_contents($fp);
   if ($response === false) {
      throw new Exception("Problem reading data from $url, $php_errormsg");
   }
   return $response;
  }

  function generate_key_post($url, $data) {
    return do_post_request($url, http_build_query($data));
  }

  $data['Action'] = 'GenerateKey';
  $data['KeyMode'] = 512;
  $data['KeyBase'] = 32;
  $data['Hyphens'] = 1;
  $data['EncryptedConstant'] = 2113444489;
  $data['PrivateKey'] = '00C98B2SF9UBJA605AJX53GJFXJV8UH4A6PY2L6CV4MAMV7V3ERRVY99Y72V2P77Z2J3KBPGWR3WXKG5GF9Z6CKXJHY5VUMBTQ66H2MRZPCU00DLFJ675JTTTNEK00DLFJ675JTTTNEK';
  $data['PublicKey'] = '0201B810DA4A1ADD4351378790A98138533067CP4S86R7D8THS45GBCVUM635EPRQRMYRP3DAA5DUPZ6ABDSFP7F5ACP7ERGH4A7Y6B6NW6NMMBZF83WVER9Y4MMBNLBQDKR7KFVLGLV067CFDQCWCHGQVVRN24DECEPBL96YJQJTVDCRTNQG3E4WW4GK4GQ5X5L5H88D3XYHCBRBNASPD3P5CNYFKFHBCSDHHD6WPTCC4XVSM5S88067C2JSTCMVT48C8HC7SHKGTFJBM28P6XTBCNWHMV6J6KN6W5Q9TQLVR285U6GVCAAUTZLRTPSRGDQ742B4742XF4MACRR747YDP5FZZ9D';
  $data['RegName'] = 'Vladimir Sukhov';

  $regkey = generate_key_post('http://yoursite.com/cgi-bin/keygen', $data);
  echo('Registration name: Vladimir Sukhov<br/>Registration Key: '.$regkey);

?>
You have to put these sources to .php file, and use this file as a keys generator link in Plumis. Note, you have to change secure constants in these sources to your once and also, change string

Code: Select all

$data['RegName'] = 'Vladimir Sukhov';
to the variables that plumis sends to keys generator, for example

Code: Select all

$data['RegName'] = $_GET['CUSTOMER_FIRSTNAME'].' '.$_GET['CUSTOMER_LASTNAME'].' '.$_GET['CUSTOMER_EMAIL'];
You have to look at Plumis manual to get real variables names that it sends to keys generators.
3. If you are worry that somebody can access your server and get the files described in methods #1 and #2, then you may use same method like #2, but send the PrivateKey value through Plumis, for example, the part of php page will look like:

Code: Select all

  $data['Action'] = 'GenerateKey';
  $data['KeyMode'] = 512;
  $data['KeyBase'] = 32;
  $data['Hyphens'] = 1;
  $data['EncryptedConstant'] = 2113444489;
  $data['PrivateKey'] = $_GET['PrivateKey'];
  $data['PublicKey'] = '0201B810DA4A1ADD4351378790A98138533067CP4S86R7D8THS45GBCVUM635EPRQRMYRP3DAA5DUPZ6ABDSFP7F5ACP7ERGH4A7Y6B6NW6NMMBZF83WVER9Y4MMBNLBQDKR7KFVLGLV067CFDQCWCHGQVVRN24DECEPBL96YJQJTVDCRTNQG3E4WW4GK4GQ5X5L5H88D3XYHCBRBNASPD3P5CNYFKFHBCSDHHD6WPTCC4XVSM5S88067C2JSTCMVT48C8HC7SHKGTFJBM28P6XTBCNWHMV6J6KN6W5Q9TQLVR285U6GVCAAUTZLRTPSRGDQ742B4742XF4MACRR747YDP5FZZ9D';
  $data['RegName'] = $_GET['CUSTOMER_FIRSTNAME'].' '.$_GET['CUSTOMER_LASTNAME'].' '.$_GET['CUSTOMER_EMAIL'];

  $regkey = generate_key_post('http://yoursite.com/cgi-bin/keygen', $data);
  echo('Registration name: Vladimir Sukhov<br/>Registration Key: '.$regkey);
and also, in the Plumis service you will have to enter following link to custom keys generator:
http://mysite.com/keygen.php?PrivateKey ... 675JTTTNEK
What is advantage of this method - private key value is not stored on the server, and even if somebody will key keys generator files, without PrivateKey they will not be able to generate valid registration keys.

Hope this helps!
elore
Posts: 25
Joined: Sat Oct 23, 2010 4:27 pm

Re: Using CGI to generate license

Post by elore »

Thanks a lot for your detailed answer. I thought about these approaches. I think combination of these 2 options is the best way.

But I think it's not really stable to use IP address - it would be better to check reverse DNS by IP.

And in second point I think I will need to make an assumption that my server is secure enough. Otherwise there is NO way to implement it securely.

Thanks.
Enigma
Site Admin
Posts: 2945
Joined: Wed Aug 20, 2008 2:24 pm

Re: Using CGI to generate license

Post by Enigma »

Really, I think it is not a problem at all. Nobody can get access to your webserver (normally), and no way the traffic can be hooked between Plimus and server.

I think you may use just usual PHP keygen (#2)..
elore
Posts: 25
Joined: Sat Oct 23, 2010 4:27 pm

Re: Using CGI to generate license

Post by elore »

No, #2 is not enough.

Here is what needs to be added to php keygen:

Code: Select all

$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$hostname = substr($hostname, -10); // plimus.com
if( $hostname != "plimus.com")
{
	die("Sorry, only for plimus :)");
}
And it works well.
Enigma
Site Admin
Posts: 2945
Joined: Wed Aug 20, 2008 2:24 pm

Re: Using CGI to generate license

Post by Enigma »

You should also take a look at #3, it is much secure.

Let me explain shortly.

For generating registration keys there are using 2 keys, PrivateKey and PublicKey. To verify registration key there is using only 1 - PublicKey. Until nobody knows your PrivateKey, nobody will be able to generate reg keys, even if they knows PublicKey!

Ok, good luck!
elore
Posts: 25
Joined: Sat Oct 23, 2010 4:27 pm

Re: Using CGI to generate license

Post by elore »

If we assume that my server is secure enough, then it's better to keep Private key only on my server. Otherwise the Private Key will be stored in Plimus and will be passed through the network in open form (not by SSL).

So, I think #2 is more secure. :)
Post Reply