Secure communication between arduino and PHP using RC4 and base64

advertisements

I'm trying to make a mildly secure communication between Arduino and PHP. I can not use SSL for lack of power on the Arduino. So I wanted to use RC4 to encrypt data from PHP, and receive into the Arduino and decrypt. also encrypt from the Arduino and send to PHP.

The problem is that the encrypted data sent from PHP, do not coincide in the Arduino.

On PHP I get HesshwkfFk8Q in base64 and in the Arduino i get nZcwrlpZEr0V in base64. different results when they should be equal.

I think I have a wrong Arduino RC4 implementation. I'm using this https://github.com/adamvr/arduino-base64

This is the code:

Arduino

#include <Base64.h>

unsigned char S[256];
char has[512];

#define S_SWAP(a,b) do { int t = S[a]; S[a] = S[b]; S[b] = t; } while(0)

void rc4(char *key, char *data){
     int i,j;

     for (i=0;i<256;i++){
         S[i] = i;
     }

     j = 0;
     for (i=0;i<256;i++){
         j = (j+S[i]+key[i%strlen(key)]) %256;
         S_SWAP(S[i],S[j]);
     }

     i = j = 0;
     for (int k=0;k<strlen(data);k++){
         i = (i+1) %256;
         j = (j+S[i]) %256;
         S_SWAP(S[i],S[j]);
         has[k] = data[k]^S[(S[i]+S[j]) %256];
     }
     has[strlen(data)+1] = '\0';

}

void setup() {
  Serial.begin(9600);
  char key[] = "Hello";
  char sdata[] = "secretMsg";

  rc4(key,sdata);
  Serial.print("Encrypted : ");

  char out[100];
  base64_encode(out,has,strlen(has));
  Serial.println(out);

  char out2[100];
  base64_decode(out2,out,strlen(out));

  rc4(key,out2);
  Serial.print("Decrypted : ");

  Serial.println(has);

}

void loop(){

}

PHP

  <?php
    $key = 'Hello';
    $msg = 'secretMsg';
    $encrypted = rc4_crypt($key, $msg);  

    echo 'encrypted b64: ', base64_encode($encrypted) ,'<br>';
    echo "decrip: " , rc4_decrypt($key,rc4_crypt($key, $msg));
    exit;

    function rc4_crypt($key,$msg) {
          $td = mcrypt_module_open('arcfour', '' , 'stream', '');
    mcrypt_generic_init($td, $key, null);
    $encrypted = mcrypt_generic($td, $msg);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
    return $encrypted;
    }  

    function rc4_decrypt($key,$msg) {
    return rc4_crypt($key,$msg);
    }
  ?>


I had the same problem and I can confirm you that your RC4 function in Arduino is wrong, you can use this instead:

unsigned char S[256];
unsigned int i, j;    

void swap(unsigned char *s, unsigned int i, unsigned int j) {
        unsigned char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }

    /* KSA */
    void rc4_init(unsigned char *key, unsigned int key_length) {
        for (i = 0; i < 256; i++)
            S[i] = i;

        for (i = j = 0; i < 256; i++) {
            j = (j + key[i % key_length] + S[i]) & 255;
            swap(S, i, j);
        }

        i = j = 0;
    }

    /* PRGA */
    unsigned char rc4_output() {
        i = (i + 1) & 255;
        j = (j + S[i]) & 255;

        swap(S, i, j);

        return S[(S[i] + S[j]) & 255];
    }