4

I am a newbie to API development, but have successfully managed to implement CI REST Server by Phil Sturgeon and Chris Kacerguis by reading all articles I could find, but there is one answer that eludes me, from the following question: CodeIgniter REST API Library Ajax PUT throwing 403 Forbidden and How can I generate an API Key in My own Controller in Codeigniter.

I have added the "boguskey" to the database as suggested in the first question's accepted answer, but I am confused about security here. If I need to have a hard-coded API key to generate new keys, and someone can view the header to see this bogus API key, how do I secure my API then from someone who then use this API key to generate tons of API keys for us within my API? If I do not add the boguskey, then I get "Invalid API key" regardless of which function I call.

My apologies if this is a stupid question, but if someone has an example of how I can generate keys securely (or at least inform me if I am misinterpreting the situation) I will greatly appreciate it.

Community
  • 1
  • 1
Kobus Myburgh
  • 1,114
  • 1
  • 17
  • 46
  • Has anybody any idea here? No research I do shows me something that I can use. I really hope to get some feedback here. Thanks in advance! – Kobus Myburgh Jul 23 '14 at 08:31
  • Does your bogus key have enough permissions to use the http path to your api? The "level" of the key needs to have the at least or greater permission to use the end path. GETS might have a low level, 1, where PUTS, POSTS and DELETES would have a different key with higher level of access permissions, maybe 10. – Nate Nolting Aug 12 '14 at 21:11
  • Hi @Withremote. the permissions is not the question here. The question is that the bogus key is clearly visible in the headers, so I am scared that people will abuse my API to create new accounts. I still have no answer though - except maybe using a very low limit. – Kobus Myburgh Aug 13 '14 at 14:56
  • @KobusMyburgh Have you resolved issue? If yes, how? I am facing same issue. I am making ajax call to generate key but to perform that action I need to pass admin key, which can be then visible to all. How do I securely create or suspend a key? – Hardiksinh Gohil Dec 23 '16 at 06:19
  • @HardiksinhGohil unfortunately not, sorry. I had to make another plan. – Kobus Myburgh Dec 24 '16 at 09:58
  • @KobusMyburgh I found option in config to override auth for specific class/method under "Override auth types for specific class/method". Thanks. – Hardiksinh Gohil Dec 26 '16 at 05:08
  • Thanks, @HardiksinhGohil. It is such an old issue on my side that I have not looked at this in over 2 years. Hope your comment helps someone else. :-) – Kobus Myburgh Dec 27 '16 at 18:00

1 Answers1

2

To ensure the max security you should encrypt all the sent data, then if the API could decrypt it correctly you should be fine, you can use RSA encryption, so if any one intercept the request he cant decrypt or clone it, But RSA is not designed to be used on long blocks of plain text, so you can use hybrid encryption. Namely, this involves using RSA to asymmetrically encrypt a symmetric key.

Randomly generate a symmetric encryption (say AES) key and encrypt the plain text message with it. Then, encrypt the symmetric key with RSA. Transmit both the symmetrically encrypted text as well as the asymmetrically encrypted symmetric key.

The API can then decrypt the RSA block, which will yield the symmetric key, allowing the symmetrically encrypted text to be decrypted.

To implement RSA on CodeIgniter you can use this class, call the file on your controller require_once("RSA.php");.

On the API consumer controller make an array which will contain the data and the the asymmetrically encrypted symmetric key

$request_data = array();
$request_data["username"] = "taghouti";
$request_data["project"] = "Secured_API";
$serialized_request_data = serialize($request_data);
$enc = new RSAEnc($serialized_request_data,'public_key');
$encrypted = $enc->result();
$request_data = array(
    "data" => base64_encode($encrypted->result), 
    "key" => base64_encode($encrypted->key)
);

And on the API controller you should try to decrypt the symmetric key using your private key, if the decryption done successfully you should be fine

if ($_POST["key"]) {
  $key = base64_decode($_POST["key"]);
  $_POST["key"] = null;
  if (isset($_POST["data"])) {
    $data = base64_decode($_POST["data"]);
    $dec = new RSADec($data, 'private_key', $key);
    $decrypted = $dec->result();
    if($decrypted->success !== true) die("Decryption failed");
    $decrypted = @unserialize($decrypted->result);
    $_POST = is_array($decrypted) ? $decrypted : array();
    $this->_post_args = $_POST;
  }
} 

if($this->input->post('project') && $this->input->post('username')) {
  //Enjoy
} else {
  die('data parsing error');
}
Taghouti Tarek
  • 104
  • 1
  • 10