• Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Java and Wicket web development thoughts, tutorials, and tips

roman@coderdreams.com
Coder DreamsCoder Dreams
  • Fat Cats Boardgame
  • Wicket UI Library
  • About Me

Creating secure encrypted links in Wicket with Apache Shiro

November 16, 2019 Posted by Roman Sery wicket No Comments

Creating secure encrypted URL’s in your application is a very common need in web development, especially when you need to integrate with 3rd parties.

A good example that I personally worked on was a points rewards site which allowed 3rd parties to embed encrypted links in their sites and emails. When their users would arrive to our site through these links, they would be rewarded in some way. These type of encrypted REST API’s are very useful for creating user/award specific one-time links.

Dependencies

We will rely on two great libraries: Apache Shiro and BouncyCastle. BouncyCastle provides some more secure encryption modes not available in Shiro. So to get started we will add these two dependencies to our project:

<dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>1.4.1</version>
</dependency>
<dependency>
      <groupId>org.bouncycastle</groupId>
      <artifactId>bcprov-ext-jdk15on</artifactId>
      <version>1.64</version>
</dependency>

Encryption Algorithms

I’m by no means an expert in encryption and will include some useful links below, but here is a short description of the two methods provided. Of course you can add others depending on your specific needs and those of your partners/clients. We ran into difficulties because some 3rd parties just don’t have the technical resources to implement some types of decryption.

    • AES-CBC mode with authentication(AE)
      • Uses PKCS5 padding and a 128-bit secret key.
      • Authenticated encryption means that it’s not possible to take an encrypted string, modify it, and get another valid encrypted string.
      • This is set as the default method because you might find not everyone is able to implement the below mode.
    • AES-GCM mode
      • Similar to CBC with no padding.  Has built-in authentication.

Useful links

  • https://blog.cryptographyengineering.com/2012/05/19/how-to-choose-authenticated-encryption/
  • http://meri-stuff.blogspot.com/2012/04/secure-encryption-in-java.html
  • https://github.com/defuse/php-encryption

CipherService

We can now write a generic CipherService class which will contain encryption/decryption methods. These methods will accept a string, an optional secret key, and the encryption algorithm you wish to use. These methods will return Base-64 encoded strings that are suitable to include in a URL. You can find the full code here.

public class EncryptionService {
    String encryptAndBase64Encode(String secretString);
    String encryptAndBase64Encode(String secretString, EncryptionType type);
    String encryptAndBase64Encode(String secretString, byte[] secretKey, EncryptionType type);

    String base64DecodeAndDecrypt(String base64EncodedEncryptedString) throws Exception;
    String base64DecodeAndDecrypt(String base64EncodedEncryptedString, EncryptionType type) throws Exception;
    String base64DecodeAndDecrypt(String base64EncodedEncryptedString, byte[] secretKey, EncryptionType type) throws Exception;
}

NOTE: The decision about how and where to store your secret key is important! At the very least, don’t accidentally include it into your source code repository! I’m curious to hear some simple but secure ways you would store it.

Generating links in Wicket

Now that we have the supporting services in place, we can create a simple helper class that will create encrypted Wicket links and decrypt them:

@Service
public class Encryptor {
    private @Autowired CipherService cipherService;

    public <T extends WebPage> String createEncryptedUrl(Class<T> pageClass, PageParameters params) {
        String secretStr = Utils.mapToString(params);
        String encryptedStr = cipherService.encryptAndBase64Encode(secretStr);

        Url url = RequestCycle.get().mapUrlFor(pageClass, new PageParameters().add("enc", encryptedStr));
        return RequestCycle.get().getUrlRenderer().renderFullUrl(url);
    }

    public PageParameters decryptUrl(String encryptedStr) throws Exception {
        String decryptedStr = cipherService.base64DecodeAndDecrypt(encryptedStr);
        return Utils.stringToParams(decryptedStr);
    }
}

You can use the createEncryptedUrl() method which will create a fully qualified URL with the HTTP GET parameters aggregated and encrypted into a single ‘enc’ parameter.

You can than use the decryptUrl() method which will take an encrypted string and return an instance of PageParameters.

Conclusion

This by no means is meant as an exhaustive solution to all of your encryption needs, but it’s a great start! The full source code, including test pages that allow you to play around with the classes, is available on GitHub.

No Comments
Share
5

About Roman Sery

I've been a software developer for over 10 years and still loving Java!

You also might be interested in

Using MySQL JSON columns to simplify your data storage: Part 2

Dec 6, 2019

In part 2, we get into the nitty gritty details of how to implement the hybrid approach.

Reducing Wicket page size part 2: AttributeModifier and AttributeAppender

Sep 22, 2019

Reducing Wicket page size is one of the most important things you can do for performance. In part 2, learn how and when to replace AttributeModifier and AttributeAppender by overriding onComponentTag to squeeze out maxiumum perfomance!

Wicket quick tip #1: Async CSV export

Apr 5, 2020

A series of quick tips aimed at improving your productivity.

Categories

  • aws
  • customization
  • database
  • debugging
  • enum
  • java
  • models
  • performance
  • projects
  • react
  • software design
  • Spring
  • tool
  • Uncategorized
  • wicket

Recent Posts

  • Rent Day
  • Self-contained Wicket Fragments
  • Pros and cons of unit testing
  • Themeable React Monopoly board
  • Please dont use client-specific release branches

Recent Comments

  • TCI Express Thanks for sharing such insightful information. TCI Express truly stands out as the best air logistics company, offering fast, secure, and efficient air express and cold chain transportation services....

    Tracking down a bug in production Wicket application ·  March 25, 2025

  • Tom Error: A zip file cannot include itself Can you please correct the plugin part so it doesn't use the same folder as input?

    Deploying Spring Boot app to AWS Beanstalk with Nginx customization ·  September 3, 2021

  • Golfman: Reality always wins I've used both Wicket and front-end JS frameworks and, having worked extensively on both, I can tell you that "Speed of development" is definitely NOT with the JS frameworks. You basically end up...

    Five reasons you should use Apache Wicket ·  August 29, 2021

  • Kiriller Sorry can not agree with you, wicket might be a well built technical framework. But the advantages of using a front-end framework like react.js and vue.js can not be beaten by Wicket nowadays. - Speed...

    Five reasons you should use Apache Wicket ·  August 23, 2021

  • Bernd Lauert Sorry but i have to refute your claims with the following arguments: 1. the Wicket community may be small but it is also very responsive, you usually get a helpful answer from the core devs on the...

    Five reasons you should use Apache Wicket ·  July 1, 2021

Archives

  • May 2021
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019

Contact Me

Send Message
Prev Next