<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="215052" data-post-id="215052">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hauleth" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/120/18942_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hauleth
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>That is why if you have these thee letters anywhere in your code <code>AES</code> then you are probably vulnerable. If you want to do it right you have few options:</p>
<ul>
<li>If there is no additional requirements - encrypt only on transport layer, like TLS, and call it a day</li>
<li>Use good token implementations, like <a href="https://paseto.io" rel="noopener nofollow ugc">PASETO</a> (<a href="https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid" rel="noopener nofollow ugc">JOSE (used by JWT) is plagued with problems</a>)</li>
<li>Use <a href="https://doc.libsodium.org/secret-key_cryptography/secretbox" rel="noopener nofollow ugc">foolproof API from entrusted authors</a> instead of building the protocol on your own</li>
</ul>
<p>Doing crypto on your own is <strong>enormously hard</strong>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="215052" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-215052" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="215052"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="215084" data-post-id="215084">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mattbaker" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mattbaker/120/3698_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mattbaker
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is so interesting! Thanks for sharing that about CBC, I learned something new too!</p>
<p>I like that you pointed to more resources in your follow up comment, since knowing what <em>not</em> to do is only have the battle <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="215084" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-215084" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="215084"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="215089" data-post-id="215089">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="tomciopp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tomciopp/120/4900_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  tomciopp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Agreed mostly, if you’re going to use AES, make sure it is AES-GCM. However, more people seem to be advocating for XSalsa20-Poly1305 these days. Use libsodium or NaCl bindings if you can. Write the least amount of code to interface with existing battle tested libraries.</p>
<p>If you find yourself actually implementing algorithms and you’ve never done it before stop. You’re 100% likely to do something incorrectly and your system will be insecure.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="215089" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-215089" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="215089"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="215123" data-post-id="215123">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>That Paragon website is a goldmine.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="215123" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-215123" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="215123"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="215156" data-post-id="215156">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hauleth" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/120/18942_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hauleth
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mattbaker" data-post="13" data-topic="39493">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mattbaker/48/3698_2.png" class="avatar"> mattbaker:</div>
<blockquote>
<p>Thanks for sharing that about CBC</p>
</blockquote>
</aside>
<p>Just be aware, that it applies to all unauthenticated encryption, not only CBC. Of course you can build authenticated protocol using CBC, but <a href="https://crypto.stackexchange.com/a/205/28013" rel="noopener nofollow ugc">that is still full of pitfalls</a>.</p>
<aside class="quote no-group" data-username="tomciopp" data-post="14" data-topic="39493">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tomciopp/48/4900_2.png" class="avatar"> tomciopp:</div>
<blockquote>
<p>However, more people seem to be advocating for XSalsa20-Poly1305 these days.</p>
</blockquote>
</aside>
<p>Small correction, XChaCha20 not XSalsa20. The difference is compression function that optimises better on the X86-64 CPUs, as there is reduced dependency between rows. <a href="https://github.com/openssl/openssl/issues/5523" rel="noopener nofollow ugc">However XChaCha20 is still not standardised by IETF and due to that is not included in OpenSSL</a>.</p>
<aside class="quote no-group" data-username="tomciopp" data-post="14" data-topic="39493">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tomciopp/48/4900_2.png" class="avatar"> tomciopp:</div>
<blockquote>
<p>Use libsodium or NaCl bindings if you can. Write the least amount of code to interface with existing battle tested libraries.</p>
</blockquote>
</aside>
<p>That.</p>
<aside class="quote no-group" data-username="tomciopp" data-post="14" data-topic="39493">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/tomciopp/48/4900_2.png" class="avatar"> tomciopp:</div>
<blockquote>
<p>If you find yourself actually implementing algorithms and you’ve never done it before stop.</p>
</blockquote>
</aside>
<p>Actually not really. Implementing most of the cryptographic primitives (with exception to AES due to the design issues) is quite easy and straightforward. What is hard is how to implement <strong>protocols</strong>, as this is where most of the cryptographic problems is happening. Erlang has quite nice API for using the primitives, which is simple, the hard part is how to join primitives with other to have secure protocol.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="215156" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-215156" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="215156"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="307757" data-post-id="307757">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="chriscohoat" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/chriscohoat/120/8053_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  chriscohoat
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I know I’m a bit late to the game here … but I spent all day trying to port this related (and reasonably-looking NodeJS call):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">const decryptedData = CryptoJS.AES.decrypt(
     ciphertext,
     passphrase
).toString(CryptoJS.enc.Utf8);
</code></pre>
<p>to Elixir. In my case I was passing in a Base64 encoded string with a <code>Salted</code> prefix.</p>
<p>In crypto-js there’s a function called <code>parse</code>:</p>
<p><a href="https://github.com/brix/crypto-js/blob/develop/src/cipher-core.js#L610" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/brix/crypto-js/blob/develop/src/cipher-core.js#L610</a></p>
<p>My implementation (thanks a lot <a class="mention" href="/u/mattbaker" rel="nofollow">@mattbaker</a> for your help):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule SSODecryption do
  def parse(openSSLStr) do
    {:ok, ciphertext_b64} = Base.decode64(openSSLStr)

    &lt;&lt;salted_indicator::binary-size(8), salt::binary-size(8), ciphertext::binary&gt;&gt; =
      ciphertext_b64

    case salted_indicator do
      "Salted__" -&gt;
        {salt, ciphertext}

      _ -&gt;
        {:error, "No salt found"}
    end
  end

  def parse_and_decrypt(openSSLStr, passphrase, algo \\ :aes_256_cbc) do
    case parse(openSSLStr) do
      {:error, reason} -&gt;
        {:error, reason}

      {salt, ciphertext} -&gt;
        {key, iv} = derive_key_and_iv(passphrase, salt)
        perform_decryption(ciphertext, iv, key, algo)
    end
  end

  defp derive_key_and_iv(passphrase, salt) do
    # Concatenate the passphrase and salt as the starting point for hash computations.
    passphrase_salt = passphrase &lt;&gt; salt

    # Compute the first hash using the passphrase and salt.
    a = :crypto.hash(:md5, passphrase_salt)

    # For subsequent hashes, concatenate the result of the previous hash with the original passphrase and salt.
    b = :crypto.hash(:md5, a &lt;&gt; passphrase_salt)
    c = :crypto.hash(:md5, b &lt;&gt; passphrase_salt)

    # The IV is derived from the first two hash outputs.
    iv = a &lt;&gt; b

    # The key is derived from the third hash output.
    key = c

    {key, iv}
  end

  defp perform_decryption(ciphertext, iv, key, algo) do
    try do
      case :crypto.crypto_one_time(algo, iv, key, ciphertext,
             encrypt: false,
             padding: :pkcs_padding
           ) do
        result when is_binary(result) -&gt;
          case Jason.decode(result) do
            {:ok, decoded} -&gt; {:ok, decoded}
            {:error, _reason} -&gt; {:error, "Failed to decode JSON"}
          end

        _reason -&gt;
          {:error, "Decryption failed for an unknown reason"}
      end
    rescue
      _exception -&gt;
        {:error, "Decryption failed"}
    end
  end
end
</code></pre>
<p>I’m not positive about the error handling and it only works for the salted case right now, but it seems to let me move some NodeJS code away. Thanks again for the answers on this thread.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="307757" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/porting-node-js-encryption-function-to-elixir/39493/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-307757" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="307757"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>