<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Dhiraj Ray</title>
    <description>The latest articles on Forem by Dhiraj Ray (@only2dhir).</description>
    <link>https://forem.com/only2dhir</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F111914%2F34dcd9e4-dcae-414d-a13d-d3afcf9c5344.jpeg</url>
      <title>Forem: Dhiraj Ray</title>
      <link>https://forem.com/only2dhir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/only2dhir"/>
    <language>en</language>
    <item>
      <title>AES vs ChaCha20: Explained While Building Real Crypto Tools</title>
      <dc:creator>Dhiraj Ray</dc:creator>
      <pubDate>Tue, 20 Jan 2026 12:23:49 +0000</pubDate>
      <link>https://forem.com/only2dhir/aes-vs-chacha20-explained-while-building-real-crypto-tools-1lfh</link>
      <guid>https://forem.com/only2dhir/aes-vs-chacha20-explained-while-building-real-crypto-tools-1lfh</guid>
      <description>&lt;p&gt;Over the years, I’ve built and maintained multiple online cryptography tools — AES encryption, ChaCha20 encryption, RSA encryption, and several hashing utilities.&lt;/p&gt;

&lt;p&gt;On the surface, all these tools look similar. You provide some input, click a button, and get encrypted or hashed output.&lt;/p&gt;

&lt;p&gt;But while working on these tools and reading user comments, I noticed a recurring pattern:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;many users are confused about &lt;em&gt;why&lt;/em&gt; different encryption algorithms require different inputs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why does ChaCha20 need a nonce?&lt;br&gt;&lt;br&gt;
Why does AES talk about modes and padding?&lt;br&gt;&lt;br&gt;
Aren’t they all just “encryption” in the end?&lt;/p&gt;

&lt;p&gt;This post is my attempt to answer those questions in a practical, beginner-friendly way.&lt;/p&gt;




&lt;h2&gt;
  
  
  Encryption Looks Simple — Until You Build It
&lt;/h2&gt;

&lt;p&gt;From a high level, encryption tools feel identical. You enter plaintext, provide a secret key, and receive ciphertext.&lt;/p&gt;

&lt;p&gt;But once you implement them, the differences become obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some algorithms ask for an IV&lt;/li&gt;
&lt;li&gt;Some require a nonce&lt;/li&gt;
&lt;li&gt;Some expose modes&lt;/li&gt;
&lt;li&gt;Others hide complexity to prevent misuse&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These differences come directly from how each algorithm is designed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AES Has So Many Options
&lt;/h2&gt;

&lt;p&gt;AES (Advanced Encryption Standard) is a &lt;strong&gt;block cipher&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It encrypts data in fixed-size blocks (128 bits at a time).&lt;/p&gt;

&lt;p&gt;Because of this, AES must be used with a &lt;em&gt;mode of operation&lt;/em&gt; such as CBC, CTR, or GCM.&lt;/p&gt;

&lt;p&gt;That’s why AES tools often expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encryption mode&lt;/li&gt;
&lt;li&gt;Initialization Vector (IV)&lt;/li&gt;
&lt;li&gt;Padding scheme&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AES is also extremely fast on modern CPUs thanks to hardware acceleration (AES-NI), which is why it dominates server-side environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why ChaCha20 Needs a Nonce
&lt;/h2&gt;

&lt;p&gt;ChaCha20 works very differently.&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;stream cipher&lt;/strong&gt;, meaning it generates a pseudorandom keystream and XORs it with plaintext.&lt;/p&gt;

&lt;p&gt;Instead of modes and padding, ChaCha20 relies on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A 256-bit secret key&lt;/li&gt;
&lt;li&gt;A nonce (number used once)&lt;/li&gt;
&lt;li&gt;An internal counter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Users often ask why the nonce matters so much.&lt;br&gt;&lt;br&gt;
The reason is simple: &lt;strong&gt;stream ciphers must never reuse the same keystream&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to experiment with nonce reuse and see how output changes, a&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.devglan.com/online-tools/chacha20-encryption-decryption" rel="noopener noreferrer"&gt;ChaCha20 encryption tool&lt;/a&gt;&lt;br&gt;&lt;br&gt;
can make this behavior very clear.&lt;/p&gt;




&lt;h2&gt;
  
  
  AES vs ChaCha20 (Quick Comparison)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;AES&lt;/th&gt;
&lt;th&gt;ChaCha20&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cipher Type&lt;/td&gt;
&lt;td&gt;Block cipher&lt;/td&gt;
&lt;td&gt;Stream cipher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Random Input&lt;/td&gt;
&lt;td&gt;IV (mode-dependent)&lt;/td&gt;
&lt;td&gt;Nonce&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modes Required&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Padding&lt;/td&gt;
&lt;td&gt;Often required&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware Acceleration&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile Performance&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;AES and ChaCha20 both solve the same problem — turning readable data into unreadable data — but they approach it very differently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AES&lt;/strong&gt; shines on servers and compliance-heavy systems
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ChaCha20&lt;/strong&gt; excels on mobile, browsers, and constrained environments
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you understand &lt;em&gt;why&lt;/em&gt; certain fields exist in your encryption tools, choosing the right algorithm becomes much easier.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Read the full in-depth guide with real-world mistakes and FAQs:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.devglan.com/crypto/aes-vs-chacha20" rel="noopener noreferrer"&gt;https://www.devglan.com/crypto/aes-vs-chacha20&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>aes</category>
      <category>chacha20</category>
    </item>
    <item>
      <title>An Introduction to Spring Cloud Gateway</title>
      <dc:creator>Dhiraj Ray</dc:creator>
      <pubDate>Sat, 15 Jun 2019 12:02:18 +0000</pubDate>
      <link>https://forem.com/only2dhir/an-introduction-to-spring-cloud-gateway-3o89</link>
      <guid>https://forem.com/only2dhir/an-introduction-to-spring-cloud-gateway-3o89</guid>
      <description>&lt;p&gt;&lt;a href="https://aws.amazon.com/api-gateway/"&gt;An API Gateway&lt;/a&gt; provides a single entry point for all the microservices running downstream. There are many gateway solutions available such as Zuul, Linkerd, Nginx, etc. but in this article, we will specifically discuss Spring Cloud Gateway - a reactive Gateway built upon Project Reactor, Spring WebFlux, and Spring Boot 2.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zuul Vs Spring Cloud Gateway
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.devglan.com/spring-cloud/spring-cloud-gateway"&gt;Spring Cloud Gateway&lt;/a&gt; is a non-blocking gateway while Zuul1 is a blocking gateway. In case of non-blocking, the main thread is always available to serve the request and other multiple threads process those requests asynchronously in the background and once the request is completely processed the response is returned. Hence non-blocking model requires a less no of resources to serve the same amount of requests as compared to blocking gateway.&lt;/p&gt;

&lt;p&gt;Though Zuul2 is also a non-blocking gateway but Spring Cloud does not provide integration with Zuul2 out of the box and there are many features in spring cloud gateway that is not available in Zuul2 for publicly such as request limiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spring Cloud Gateway Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lEGOwJ8r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/2N8AgtH.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lEGOwJ8r--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/2N8AgtH.png" alt="Spring Cloud Gateway Architecture"&gt;&lt;/a&gt;&lt;br&gt;
Once a request reaches to the gateway, the first thing gateway does is to match the request with each of the available route based on the predicate defined. Once, the route has matched the request moves to web handler and the filters will be applied to the request. There are many out of the box filters provided by the gateway itself to modify the request header as well as the body. Pre-filters are applied specifically to a route whereas global filters can be applied to all the route request. Global filters can be applied to perform authentication and authorization of all the request at one place.&lt;/p&gt;
&lt;h2&gt;
  
  
  Route Definition in Spring Cloud Gateway
&lt;/h2&gt;

&lt;p&gt;Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if the aggregate predicate is true. &lt;/p&gt;

&lt;p&gt;Below is an example of a route that has a predicate defined to match all the request URL with /api/v1/queue/** and apply a pre-filter to rewrite the path. There is another filter applied to modify the request header and then route the request to load balanced FIRST-SERVICE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/v1/first/**"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rewritePath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/api/v1/first/(?.*)"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/${remains}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addRequestHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"X-first-Header"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"first-service-header"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lb://FIRST-SERVICE/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//downstream endpoint  lb - load balanced&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"queue-service"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;

                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Below is the equivalent .yaml configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;spring:&lt;/span&gt;
  &lt;span class="nl"&gt;cloud:&lt;/span&gt;
    &lt;span class="nl"&gt;gateway:&lt;/span&gt;
      &lt;span class="nl"&gt;routes:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nl"&gt;id:&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;
        &lt;span class="nl"&gt;uri:&lt;/span&gt; &lt;span class="nl"&gt;lb:&lt;/span&gt;&lt;span class="c1"&gt;//FIRST-SERVICE&lt;/span&gt;
        &lt;span class="nl"&gt;predicates:&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;/**&lt;/span&gt;
        &lt;span class="nl"&gt;filters:&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;RewritePath&lt;/span&gt;&lt;span class="o"&gt;=/&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;/(?.*),&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;$\&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="n"&gt;remains&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;AddRequestHeader&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nc"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  WebSocket Connection in Spring Cloud gateway
&lt;/h2&gt;

&lt;p&gt;The ability to have real-time two-way communication between the client and the server is a key feature in most modern web apps. As we know, Zuul 1 does not support WebSocket connection whereas Spring Cloud Gateway provides excellent and easily configurable &lt;a href="https://www.devglan.com/spring-cloud/spring-cloud-gateway-websockets"&gt;support for WebSockets&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Below is a route definition for load-balanced WebSockets. For notification-service, we have a route configured as any request matching with the path /websocket will be routed to notification-service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/websocket/**"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rewritePath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/websocket/(?.*)"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/${remains}"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"lb://NOTIFICATION-SERVICE/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"notification-service"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are tons of features provided by Spring Cloud Gateway out of the box. You can get started with this &lt;a href="https://www.devglan.com/spring-cloud/spring-cloud-gateway-example"&gt;example on Spring Cloud Gateway&lt;/a&gt; to know all the features of Spring Cloud Gateway.&lt;/p&gt;

</description>
      <category>springcloudgateway</category>
      <category>apigateway</category>
      <category>microservices</category>
      <category>springcloud</category>
    </item>
  </channel>
</rss>
