Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Implementing Secure Automatic Authentication in ColdFusion  : Page 5

Don't just set a plain-text cookie to match users with stored server data; let users log on automatically and securely by taking advantage of CF's ability to interact with Java.


advertisement

Verifying a Digital Signature
The Java Encryption class is almost complete. All you need now is a method to verify signatures, and again, you can use the Signature class. Create a Signature instance and initialize it for signing. Next, pass the same data you used to create the previous signature through the update method. Again, you can call the update method as many times as you want. After feeding all the data to the Signature object you can verify it by calling the verify method. Pass the signature you created previously with the sign method. The verify method expects the signature to be a byte array, so you use the String getBytes method to work around CF's shortcomings. The verify method returns a Boolean value indicating whether the signature is valid for the data supplied to it. Here's the verify method implementation.

      public boolean verify(String signature, String buffer) throws Exception
      {
         Signature dsa = Signature.getInstance("SHA/DSA");
         dsa.initVerify(publicKey);
         dsa.update(buffer.getBytes());
         return dsa.verify(signature.getBytes());
      }
Adding the verify method completes the Encryption class. Before you can call it from CF, you need to compile the class. You will also need to update CF's classpath environment variable in the CF administrator under the Java settings section. Take a look at the documentation for help on how to do this.

Calling the Encryption Class from CF
Using the Encryption class from CF is rather easy thanks to the CFObject tag. It lets you create Java class instances and call their public methods. There are a few problems related to use of CFObject and Java classes. One of those problems is how CF deals with overloaded methods. Defining more than one method in a single class with the same name is known as method overloading. Java uses the method argument variable types to determine which method to use for any given call. However, because CF is a typeless language, it is often hard or impossible for CF to resolve overloaded methods. For this reason I recommend not using overloaded methods in classes that are to be called from CF. Another problem with CFObject to beware of is that you have to restart the CF application server anytime you make changes to any Java class files that you call.

First, create an Encryption class instance and use it to generate a key pair and write them to disk.

      <cfobject type="JAVA" action="Create" name="crypt" 
         class="Encryption">
      <cfscript>
         crypt.generateKeys();
         crypt.writeKeys("c:\public.key", "c:\private.key");
      </cfscript>
The preceding example uses the CFObject tag to create an instance of class Encryption and assign it to a local CF variable. You can also create a pointer to the Encryption class using the CreateObject function; however, you will need to call the class' init method to instantiate it. Here's an example.



      <cfscript>
         crypt = CreateObject("JAVA", "Encryption");
         crypt.init();
      </cfscript>
After creating the instance of the Encryption class you can call methods in much the same way you would in Java. After executing the preceding code you have the public and private keys written to disk. With those in hand you can create a signature. Assuming that you're going to create the signature in a different CS script you need to create a new instance of the Encryption class. You won't be generating a key pair this time, but you need to read in the private key before creating the signature. You don't need the public key to create a signature.

      <cfobject type="JAVA" action="Create" name="crypt" 
         class="Encryption">
      <cfscript>
         crypt.readPrivateKey("c:\private.key");
         signature = ToBase64(crypt.sign("mliotta@devx.com"));
      </cfscript>
The preceding code successfully signs my email address and assigns the newly created digital signature it to the local CF variable signature. However, it may be hard to use the signature in its current form because it is binary data. The CF function ToBase64 converts binary strings into base64 strings. You can display Base64 strings as plain text with no problems. To verify the signature you need to convert it back into binary by calling the CF ToBinary function. After converting it back to binary, verification is a simple matter of calling the verify method. However, the verify method needs the public key to verify the signature, so you need to read first.

      <cfscript>
         crypt.readPublicKey("c:\public.key");
         verified = crypt.verify(ToBinary(signature), "mliotta@devx.com");
      </cfscript>
After executing the preceding code, the local CF variable verified contains a Boolean value indicating whether the signature is valid. Next, you need to be able to persist the signature on the user's machine using a cookie. Because you need to write both the user's email address and signature you'll need to make two calls to the CFCookie tag.

      <cfcookie name="email" value="mliotta@devx.com" expires="NEVER">
      <cfcookie name="signature" value="#signature#" expires="NEVER">
Automatically logging in a user is now a simple matter of verifying their signature. For example, in a separate script you would write:

      <cfscript>
         crypt = CreateObject("Java", "Encryption");
         crypt.init();
         crypt.readPublicKey("c:\public.key");
         verified = crypt.verify(ToBinary(cookie.signature), 
           cookie.email);
      </cfscript>
At this point you should be able to generate key pairs, generate and verify signatures for arbitrary data, and ultimately, use Java's encryption classes instead of the built-in CF encryption functions.


Matt Liotta is the Engineer Manager at DevX.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date