AOP – Encrypting with AspectJ using an Annotation

This is a continuation of AOP – Encrypting with AspectJ. It is expected you have read (or skimmed) that article first. This article uses the same project. The files in the project so far are these:

  • Encrypt.java
  • EncryptFieldAspect.aj
  • FakeEncrypt.java
  • Main.java
  • Person.java

The final version of EncryptFieldAspect.aj in the previous article is not exactly a “good” Aspect. The problem with it is that it isn’t very reusable. There is a one to one relationship between this Aspect and the field it encrypts. We want a one to many relationship where one Aspect works for encrypting many fields.

Another problem is there is nothing in the objects that would inform a developer that any Aspect Oriented Programming is occurring.

Step 9 – Making the Aspect reusable

Lets make the aspect reusable. Lets make one aspect with a single pointcut and a single around advice work for multiple setters in a class.

  1. In the Person class, add a forth field, DriversLicense. This field should also be encrypted.
  2. Add a getter and setter for the DriversLicense field.
  3. In the Main class, add sample code to set and later print out the DriversLicense field.
  4. In the EncryptFieldAspect, change it to work for all setters by using a * after the word set and making it work for any method that takes a string, not just the SSN setter.
package AOPEncryptionExample;

public aspect EncryptFieldAspect
{
	pointcut encryptStringMethod(Person p, String inString):
	    call(void Person.set*(String))
	    && target(p)
	    && args(inString)
	    && !within(EncryptFieldAspect);

	void around(Person p, String inString) : encryptStringMethod(p, inString) {
		proceed(p, FakeEncrypt.Encrypt(inString));
		return;
	}
}

Ok, now it is reusable but we now have another problem. It is encrypting all the fields, including FirstName and LastName. It is definitely reusable, but now we need something to differentiate what is to be encrypted from what isn’t.

Step 10 – Create an Encrypt annotation

Lets add and use an annotation to mark setters that should use encryption.

  1. Right-click on the package in Package Explorer and choose New | Annotation.
    Note: The package should already be filled out for you.
  2. Give the annotation a name.
    Note: I named mine Encrypt.
  3. Click Finish.
  4. Maybe add a comment that this annotation is for use by the Encrypt Aspect.
public @interface Encrypt
{
	// Handled by EncryptFieldAspect
}

Step 11 – Add the @Encrypt annotation to setters

  1. In the Person class, add @Encrypt above the setSSN setter.
  2. Also add @Encrypt above the setDriversLicense setter.
	@Encrypt
	public void setSSN(String inSSN)
	{
		SSN = inSSN;
	}

 

	@Encrypt
	public void setDriversLicense(String inDriversLicense)
	{
		DriversLicense = inDriversLicense;
	}
}

Step 12 – Alter the EncryptFieldAspect to work for multiple objects

Well, now that it works for any setter in the Person object that is marked with @Encrypt, the next step is to make it work for any setter marked with @Encrypt no matter what object it is in.

  1. Remove any reference to Person. We don’t even need it or the parameter ‘p’.
package AOPEncryptionExample;

public aspect EncryptFieldAspect
{
	pointcut encryptStringMethod(String inString):
		call(@Encrypt * *(String))
		&& args(inString)
		&& !within(EncryptFieldAspect);

	void around(String inString) : encryptStringMethod(inString) {
		proceed(FakeEncrypt.Encrypt(inString));
		return;
	}
}

Great, now let’s test it.

Step 11 – Test Using @Encrypt on multiple objects

Ok, let’s create a second object that has an ecrypted field to test this. Lets create a Credentials.java file with a UserName and Password fields, getters and setters. Of course the Password should be encrypted.

  1. Right-click on the package in Package Explorer and choose New | Class.
    Note: The package should already be filled out for you.
  2. Give the class a name.
    Note: I named mine Credentials.
  3. Click Finish.
  4. Add both a UserName and Password field.
  5. Add a getter and setter for both.
  6. Add the @Encrypt annotation above the setPassword setter.
package AOPEncryptionExample;

public class Credentials
{
	// UserName
	private String UserName;

	public String getUserName()
	{
		return UserName;
	}

	public void setUserName(String userName)
	{
		UserName = userName;
	}

	// Password
	private String Password;

	public String getPassword()
	{
		return Password;
	}

	@Encrypt
	public void setPassword(String password)
	{
		Password = password;
	}
}

Now lets create a Credentials object in the main() method and print out the values.

package AOPEncryptionExample;

public class Main
{
	public static void main(String[] args)
	{
		Person p = new Person();
		p.setFirstName("Billy");
		p.setLastName("Bob");
		p.setSSN("123456789");
		p.setDriversLicense("987654321");

		System.out.println("Person:");
		System.out.println("         FirstName: " + p.getFirstName());
		System.out.println("          LastName: " + p.getLastName());
		System.out.println("               SSN: " + p.getSSN());
		System.out.println("  Driver's License: " + p.getDriversLicense());
		System.out.println();

		Credentials c = new Credentials();
		c.setUserName("billybob");
		c.setPassword("P@sswd!");

		System.out.println("Person:");
		System.out.println("       UserName: " + c.getUserName());
		System.out.println("       Password: " + c.getPassword());
	}
}

Ok, test it. The output should be as follows:

Person:
         FirstName: Billy
          LastName: Bob
               SSN: #encrypted#123456789#encrypted#
  Driver's License: #encrypted#987654321#encrypted#

Person:
       UserName: billybob
       Password: #encrypted#P@sswd!#encrypted#

Well, now you have learned how to encrypt using Aspect Oriented Programming.

Here are a couple of benefits of encrypting with AOP.

  1. The crosscutting concern of security is now modular.
  2. If you wanted to change/replace the encryption mechanism, including the encryption method names, you can do that in a single place, the EncryptFieldAspect object.
  3. The code to encrypt any field in your entire solution is nothing more than an annotation, @Encrypt.
  4. The @Encrypt annotation can provide documentation in the class and in API documentation so the fact that encryption is occurring is known.
  5. You don’t have to worry about developers implementing encryption differently as it is all done in a single file in the same predictable manner.

Congratulations on learning to encrypt using AOP, specifically with AspectJ and Annotations.

What about decryption?

By the way, I didn’t show you how to decrypt. Hopefully I don’t have to and after reading you know how. Maybe in your project the design is that the getters return the encrypted values and you don’t need to decrypt. However, maybe in your design you need your getters to decrypt. Well, you should be able to impement a DecryptFieldAspect and a @Decrypt annotation for that.

If you use decrypt on the getter, the output is the same as if there were no encrypt/decrypt occuring. However, it is still enhanced security because the value is stored encrypted in memory and not as plain text in memory.

However, I have a version of the project that decrypts that you can download.

AOP Encryption example project Download

Download the desired version of the project here:

Return to Aspected Oriented Programming – Examples

2 Comments

  1. [...] Encrypting with AspectJ using an Annotation Filed under: FreeBSD — rhyous @ 8:31 pm Read more Share this:DiggRedditLike this:LikeBe the first to like this post. Leave a [...]

Leave a Reply

How to post code in comments?