eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Partner – LambdaTest – NPI EA (cat=Testing)
announcement - icon

Regression testing is an important step in the release process, to ensure that new code doesn't break the existing functionality. As the codebase evolves, we want to run these tests frequently to help catch any issues early on.

The best way to ensure these tests run frequently on an automated basis is, of course, to include them in the CI/CD pipeline. This way, the regression tests will execute automatically whenever we commit code to the repository.

In this tutorial, we'll see how to create regression tests using Selenium, and then include them in our pipeline using GitHub Actions:, to be run on the LambdaTest cloud grid:

>> How to Run Selenium Regression Tests With GitHub Actions

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Overview 

In this tutorial, we’ll discuss how to use an Initialization Vector (IV) with encryption algorithms. We’ll also discuss the best practices while using the IV.

This article assumes a basic understanding of cryptography.

We’ll be using the AES algorithm in different modes for all our examples.

2. Encryption Algorithms

Any cryptographic algorithm takes some data or plaintext and a key to produce an encrypted text or ciphertext. And, it also takes the generated ciphertext and the same key to produce the decrypted data or original plaintext back.

For example, the block cipher algorithm provides security by encrypting and decrypting fixed-length blocks. We use different encryption modes to repeatedly apply an algorithm to the entire data and dictate the type of IV to use.

In the case of block ciphers, we work with the same size blocks. If the plaintext size is smaller than the block size, we use padding. Some modes don’t use padding as they use block cipher as a stream cipher.

3. Initialization Vector (IV)

We use an IV in a cryptographic algorithm as a starting state, adding this to a cipher to hide patterns in the encrypted data. This helps avoid the need to re-issue a new key after each invocation.

3.1. Properties of an IV

We use a unique sequence or an IV for most modes of encryption. And, we should never reuse the same IV with the same key. This ensures a distinct ciphertext for the same plaintext encryption, even if we encrypt it multiple times with the same key.

Let’s look at some of the characteristics of an IV, depending on the encryption mode:

  • It has to be non-repeating
  • Based on the encryption mode, it needs to be random also
  • It need not be secret
  • It needs to be a cryptographic nonce
  • The IV of AES is always 128-bit regardless of the key length

3.2. Generating the IV

We can get an IV directly from the Cipher class:

byte[] iv = cipher.getIV();

If we’re unsure of the default implementation, we can always write our method to generate the IV. If we don’t provide an explicit IV, then Cipher.getIV() is used to implicitly get the IV. We can use any method to generate an IV as long as it complies with the properties discussed above.

First, let’s create a random IV by using SecureRandom:

public static IvParameterSpec getIVSecureRandom(String algorithm) throws NoSuchAlgorithmException, NoSuchPaddingException {
    SecureRandom random = SecureRandom.getInstanceStrong();
    byte[] iv = new byte[Cipher.getInstance(algorithm).getBlockSize()];
    random.nextBytes(iv);
    return new IvParameterSpec(iv);
}

Next, we’ll create the IV by getting the parameters from the Cipher class:

public static IvParameterSpec getIVInternal(Cipher cipher) throws InvalidParameterSpecException {
    AlgorithmParameters params = cipher.getParameters();
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    return new IvParameterSpec(iv);
}

We can use any of the above methods to generate a random, unpredictable IV. However, for some modes like GCM, we use the IV together with a counter. In such cases, we use the first few bytes, mostly 12 for the IV and the next 4 for the counter:

public static byte[] getRandomIVWithSize(int size) {
    byte[] nonce = new byte[size];
    new SecureRandom().nextBytes(nonce);
    return nonce;
}

In this case, we need to ensure that we don’t repeat the counter and that the IV is also unique.

Lastly, though not recommended, we can also use a hardcoded IV.

4. Using IV with Different Modes

As we know, the prime function of encryption is to mask plaintext so that attackers can’t guess it. Therefore, we use different cipher modes to mask the patterns within the ciphertext.

Modes like ECB, CBC, OFB, CFB, CTR, CTS, and XTS provide confidentiality. But these modes don’t protect against tampering and modification. We can add a Message Authentication Code (MAC) or a digital signature for detection. We use various implementations that provide combined modes under authenticated encryption (AE). CCM, GCM, CWC, EAX, IAPM, and OCB are a few examples.

4.1. Electronic Codebook (ECB) Mode

Electronic Codebook mode encrypts each block separately with the key. This always encrypts the identical plaintext into identical ciphertext blocks, thereby not hiding patterns well. Thus, we don’t use it for cryptographic protocols. Decryption is also equally vulnerable to replay attacks.

To encrypt data in ECB mode, we use:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
ciphertext = cipher.doFinal(data);

To decrypt data in ECB mode, we write:

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
plaintext = cipher.doFinal(cipherText);

We haven’t used any IV, so the same plaintext will result in the same ciphertext, thus making it vulnerable to attacks. Though ECB mode is the most vulnerable, it’s still the default encryption mode for many providers. So, we need to be more vigilant about explicitly setting the encryption mode.

4.2. Cyber Block Chaining (CBC) Mode

Cyber Block Chaining mode uses an IV to prevent the same plaintexts resulting in the same ciphertext. We need to take care that the IV is reliably random or unique. Otherwise, we’ll have the same vulnerability as ECB Mode.

Let’s get the random IV using getIVSecureRandom:

IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES");

First, we’ll use the IV to encrypt data using CBC mode:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);

Next, let’s pass the same IV using the IvParameterSpec object for decryption:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));

4.3. Cyber Feedback (CFB) Mode

Cyber Feedback mode is the most basic streaming mode. It’s like a self-synchronizing stream cipher. Unlike the CBC mode, we don’t need any padding here. In CFB mode, we use IV as the source of the stream generated by the cipher. Again, if we use the same IV for different encryptions, similarities might show up in the ciphertext. Here also, like the CBC mode, IV should be random. In case IV is predictable, then we lose out on confidentiality.

Let’s generate a random IV for CFB mode:

IvParameterSpec iv = CryptoUtils.getIVSecureRandom("AES/CFB/NoPadding");

Another extreme case is if we use an all-zero IV, then under CFB-8 mode, some keys may generate an all-zero IV and all-zero plaintext. In this case, 1/256 keys will generate no encryption. This will result in returning the plaintext as ciphertext.

For CBC and CFB modes, reusing an IV reveals information about the common blocks shared by two messages.

4.4. Counter (CTR) and Output Feedback (OFB) Modes

Counter mode and Output Feedback mode make a block cipher into a synchronous stream cipher. Each mode generates keystream blocks. In this case, we initialize the cipher with a particular IV. We do this primarily to allocate 12 bytes to the IV and 4 bytes to the counter. This way, we can encrypt a message of length 2^32 blocks.

Here, let’s create an IV:

IvParameterSpec ivSpec = CryptoUtils.getIVSecureRandom("AES");

For CTR mode, the initial bitstream is dependent on the IV and key. Here also, reusing an IV will cause key bitstream reuse. This, in turn, will result in breaking the security.

If the IV is not unique, then the counter may fail to provide the expected confidentiality for the blocks that correspond to the repeating counter blocks. However, the other data blocks are not affected.

4.5. Galois/Counter (GCM) Mode

Galois/Counter mode is an AEAD mode of encryption. It combines Counter mode encryption with an authentication mechanism. And, it protects both plaintext and additional authenticated data (AAD).

However, this authentication in GCM depends on the uniqueness of the IVs. We use a nonce as the IV. In case we repeat even one IV, then our implementation may be vulnerable to the attacks.

As GCM uses AES for encryption, the IV or the counter is 16 bytes. Therefore, we use the first 12 bytes as the IV and the last 4 bytes nonce as a counter.

To create an IV in GCM mode, we need to set GCMParameterSpec. Let’s create an IV:

byte[] iv = CryptoUtils.getRandomIVWithSize(12);

First, let’s get an instance of the Cipher and initialize it using the IV:

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(128, iv));

Now, we’ll create and initialize Cipher with the IV for decryption:

cipher.init(Cipher.DECRYPT_MODE, key, new GCMParameterSpec(128, iv));

Here also, we need a unique IV, else one can decipher the plaintext.

4.6. Summing up of IVs

The following table summarizes the type of IV needed for different modes:

Screenshot-2021-10-22-at-10.42.59-AM

As we have seen, reusing an IV with the same key results in loss of security. If possible, we should use more advanced modes like GCM. Also, some modes like CCM are not available in the standard JCE distribution. In this case, we can use Bouncy Castle APIs to implement it.

5. Conclusion

In this article, we showed how to use an IV in different encryption modes. We also discussed the issues and best practices while using an IV.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

Course – LSS – NPI (cat=Security/Spring Security)
announcement - icon

I just announced the new Learn Spring Security course, including the full material focused on the new OAuth2 stack in Spring Security:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)