title: When do AES-128-cbc encryption using nodejs and c separately,using the same key and IV but have different results
body: <p>I want to use AES-128-cbc encryption/decryption algorithm to encrypt/decrypt some data,and use nodejs to encrypt the data and use c to decrypt them.But found that using the same key and IV,the two languages have different encryption results.See follows:</p>
  
  <p>nodes js code:</p>
  
  <pre><code>var crypto = require('crypto');
  
  var encrypt = function (key, iv, data) {
      var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
      var crypted = cipher.update(data, 'utf8', 'binary');
      var cbase64  =   new Buffer(crypted, 'binary').toString('base64');
      //console.log(crypted);
      //console.log(cbase64);
      crypted += cipher.final('binary');
      //console.log("hahahaaaaaa:"+crypted.toString('hex'));
      crypted = new Buffer(crypted, 'binary').toString('base64');
      //var c16 = new Buffer(crypted, 'binary').toString(16);
      //console.log(crypted);
      //console.log(c16);
  
      return crypted;
  };
  
  var decrypt = function (key, iv, crypted) {
      crypted = new Buffer(crypted, 'base64').toString('binary');
      var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
      var decoded = decipher.update(crypted, 'binary', 'utf8');
      //console.log(decoded);
      decoded += decipher.final('utf8');
      //console.log(decoded);
      return decoded;
  };
  
  var key='ABCDEFGHIJKLMNOP';
  //var iv = new Buffer(crypto.randomBytes(16));
  //var iv16 = iv.toString('hex').slice(0,16);
  var iv16='0000000000000000';
  var fs = require('fs');
  fs.readFile('file.txt','utf8',function(err,data){
    console.log(data);
      var encrypted = encrypt(key,iv16,data);
    console.log(encrypted);
     var decrypted = decrypt(key,iv16,encrypted);
    console.log(decrypted);
   fs.writeFile('encrypted.txt',encrypted,function(err){});
  });
  </code></pre>
  
  <p>c codes:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;openssl/aes.h&gt;
  #include &lt;openssl/pem.h&gt;
  #include &lt;openssl/bio.h&gt;
  #include &lt;openssl/evp.h&gt;
  
  
  #define AES_BITS 128
  #define MSG_LEN 128
  
  
  int base64_encode(char *in_str, int in_len, char *out_str)
  {
     BIO *b64, *bio;
     BUF_MEM *bptr = NULL;
      size_t size = 0;
  
       if (in_str == NULL || out_str == NULL)
           return -1;
  
       b64 = BIO_new(BIO_f_base64());
       bio = BIO_new(BIO_s_mem());
       bio = BIO_push(b64, bio);
  
       BIO_write(bio, in_str, in_len);
       BIO_flush(bio);
  
       BIO_get_mem_ptr(bio, &amp;bptr);
       memcpy(out_str, bptr-&gt;data, bptr-&gt;length);
       out_str[bptr-&gt;length] = '\0';
       size = bptr-&gt;length;
  
       BIO_free_all(bio);
       return size;
   }
  
  
  int aes_encrypt(char* in, char* key, char* out)//, int olen)
  {
      if(!in || !key || !out) return 0;
      unsigned char iv[16];
      for(int i=0; i&lt;16; ++i)
          iv[i]='0';
      //printf("size:%d",AES_BLOCK_SIZE);
      //unsigned char *iv = (unsigned char *)"0123456789ABCDEF"; 
  
  
      printf("iv: %s\n",iv);
      AES_KEY aes;
      if(AES_set_encrypt_key((unsigned char*)key, 128, &amp;aes) &lt; 0)
      {
          return 0;
      }
      int len=strlen(in);
  
  
      AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &amp;aes, iv, AES_ENCRYPT);
      return 1;
  }
  int aes_decrypt(char* in, char* key, char* out)
  {
      if(!in || !key || !out) return 0;
      unsigned char iv[16];
      for(int i=0; i&lt;16; ++i)
          iv[i]='0';
  
      //unsigned char *iv = (unsigned char *)"0123456789ABCDEF";    
  
      AES_KEY aes;
      if(AES_set_decrypt_key((unsigned char*)key, 128, &amp;aes) &lt; 0)
      {
          return 0;
      }
      int len=strlen(in);
      AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &amp;aes, iv, AES_DECRYPT);
      return 1;
  }
  
  int main(int argc,char *argv[])
  {
      char sourceStringTemp[MSG_LEN];
      char dstStringTemp[MSG_LEN];
      char dstStringTemp_base64[MSG_LEN];
      memset((char*)sourceStringTemp, 0 ,MSG_LEN);
      memset((char*)dstStringTemp, 0 ,MSG_LEN);
      strcpy((char*)sourceStringTemp, "My name is Harlan Chen!");
      //strcpy((char*)sourceStringTemp, argv[1]);
      char key[AES_BLOCK_SIZE]={0};
      int i;
      for(i = 0; i &lt; 16; i++)
      {
          key[i] = 'A' + i;
      }
  
      printf("keys:%s\n",key);    
  
      if(!aes_encrypt(sourceStringTemp,key,dstStringTemp))
      {
          printf("encrypt error\n");
          return -1;
      }
  
      /*To Base64 encrypted data  */
      base64_encode(dstStringTemp, strlen(dstStringTemp),dstStringTemp_base64);    
      printf("Base64 Encrypted data: %s\n",dstStringTemp_base64);
  
      printf("encrypted:%s\n",dstStringTemp);
      printf("enc %lu:",strlen((char*)dstStringTemp));
      for(i= 0;dstStringTemp[i];i+=1){
          printf("%x",(unsigned char)dstStringTemp[i]);
      }
      memset((char*)sourceStringTemp, 0 ,MSG_LEN);
      if(!aes_decrypt(dstStringTemp,key,sourceStringTemp))
      {
          printf("decrypt error\n");
          return -1;
      }
      printf("\n");
      printf("dec %lu:",strlen((char*)sourceStringTemp));
      printf("%s\n",sourceStringTemp);
      //for(i= 0;sourceStringTemp[i];i+=1){
      //    printf("%x",(unsigned char)sourceStringTemp[i]);
      //}
      printf("\n");
      return 0;
  }
  </code></pre>
  
  <p>nodejs results:</p>
  
  <pre><code>bogon:AES_128_encryption zexu$ node encrypt.js 
  My name is Harlan Chen!
  
  jERcWr8ZMzSJcKPGB7RYAYRpMftlThxyZcjfbFYlU3g=
  My name is Harlan Chen!
  </code></pre>
  
  <p>and the c language results:</p>
  
  <pre><code>bogon:AES_128_encryption zexu$ ./a.out 
  keys:ABCDEFGHIJKLMNOP
  iv: 0000000000000000
  Base64 Encrypted data: jERcWr8ZMzSJcKPGB7RYAf6kEOmjJgUksDtrttx4r3k=
  
  encrypted:?D\Z?34?p???X???&amp;$?;k??x?y
  enc 32:8c445c5abf1933348970a3c67b4581fea410e9a326524b03b6bb6dc78af79
  dec 23:My name is Harlan Chen!
  </code></pre>
  
  <p>Compare the two base64 strings :</p>
  
  <pre><code>jERcWr8ZMzSJcKPGB7RYAYRpMftlThxyZcjfbFYlU3g=
  jERcWr8ZMzSJcKPGB7RYAf6kEOmjJgUksDtrttx4r3k=
  </code></pre>
  
  <p>The first 21 characters are the same,the following ones are different.I don't know why.</p>