title: decrypt encrypted private key by password and openssl_decrypt
body: <p>I have a <em>private key</em> encrypted script with a password and here is its output:</p>
  
  <pre><code>{
      "iv":"Ra6kDXvh2DBiZ0r37pNuzg==",
      "v":1,
      "iter":10000,
      "ks":256,
      "ts":64,
      "mode":"ccm",
      "adata":"",
      "cipher":"aes",
      "salt":"pNN1xP7SZks=",
      "ct":"Sd8p3C3vPuW+LD
      nO9GwltDnqGOHg7+qguaEjQxzidEh5RNDh7bodJfmzmoB4DjFYQ4Qi8ferWoVV6bwJ2Q9/BnqI+
      X4A1MQY/HgVbtc9AnXj1EczsKxsUxG/ET7W+OBGQGLddzKVC38ACRg9q0NjOieOH0yTx64="
  }
  </code></pre>
  
  <p>I dont know exactly whats name of this type of encryption and I want to know how to decrypt it using a password and PHP.</p>
  
  <p>According to my research, it can be decrypted by the <code>openssl_decrypt</code> function.
  But I couldn't find how to use my parameters in this function.</p>
  
  <p>For example, I have a key called <em>salt</em> in the json that I have and I don't know what to do with it.</p>
  
  <p>Also, in the <em>openssl_decrypt</em> function, there is an input argument called <em>tag</em>. I don't know the json key that it belongs to.</p>
  
  <p>This is a sample of the code I'm using:</p>
  
  <pre><code>$ct = 'Sd8p3C3vPuW+LD
  nO9GwltDnqGOHg7+qguaEjQxzidEh5RNDh7bodJfmzmoB4DjFYQ4Qi8ferWoVV6bwJ2Q9/BnqI+
  X4A1MQY/HgVbtc9AnXj1EczsKxsUxG/ET7W+OBGQGLddzKVC38ACRg9q0NjOieOH0yTx64=';
  $method = 'aes-256-ccm';
  $password = 'Qw370207610';
  $options = 0;
  $iv = base64_decode('Ra6kDXvh2DBiZ0r37pNuzg==');
  
  $output = openssl_decrypt($ct, $method, $password, $options, $iv);
  </code></pre>
  
  <p>And I received this error:</p>
  
  <blockquote>
    <p>openssl_decrypt(): Setting of IV length for AEAD mode failed</p>
  </blockquote>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>So I have gethered that for producing the third parameter (key) that is used in openssl_decrypt, I should act like this:</p>
  
  <pre><code>$ks = 256;
  $key_length = $ks/8;
  $password = 'Qw370207610';
  $salt_base64 = 'pNN1xP7SZks=';
  $salt = base64_decode($salt_base64);
  $iterations = 10000;
  $digest_algorithm = 'sha256';
  
  $key = openssl_pbkdf2 ( $password , $salt , $key_length , $iterations , $digest_algorithm );
  </code></pre>
  
  <p>And then it can be decrypted in this way:</p>
  
  <pre><code>$ct_base64 = 'Sd8p3C3vPuW+LD
  nO9GwltDnqGOHg7+qguaEjQxzidEh5RNDh7bodJfmzmoB4DjFYQ4Qi8ferWoVV6bwJ2Q9/BnqI+
  X4A1MQY/HgVbtc9AnXj1EczsKxsUxG/ET7W+OBGQGLddzKVC38ACRg9q0NjOieOH0yTx64=';
  $ct = base64_decode($ct_base64);
  
  $ts = 64;
  $tag_length = $ts/8;
  $tag = substr($ct,-$tag_length);
  $ccm = substr($ct,0,-$tag_length);
  
  $method = 'aes-256-ccm';
  
  $options = OPENSSL_RAW_DATA;
  $iv_base64 = 'Ra6kDXvh2DBiZ0r37pNuzg==';
  $iv = base64_decode($iv_base64); // 16 bytes length
  
  $output = openssl_decrypt($ccm, $method, $key, $options, $iv, $tag);
  </code></pre>
  
  <p>However in PHP, for decrypting aes-ccm, there is just openssl, and they haven't offered another library.</p>
  
  <p>On the other hand, these functions don't accept an IV (initialization vector) larger than 12 bytes.  Because IV of my encrypted message is 16 bytes and it can not be decrypted in PHP at all !!</p>
  
  <p>Have PHP developers not thought about this? </p>
  
  <p>I have never had such problems in nodejs, but I always face some kind of restriction in PHP.</p>