/* Recode.java * Copyright (c) 1998-2005, RSA Security Inc. * * This file is used to demonstrate how to interface to an RSA * Security licensed development product. You have a * royalty-free right to use, modify, reproduce and distribute this * demonstration file (including any modified version), provided that * you agree that RSA Security has no warranty, implied or * otherwise, or liability for this demonstration file or any modified * version. * * * This application demonstrates the use of Base64 encoding binary * data into a ASCII printable form. The Base64-encoded data is then * decoded to yield the original data. * */ package com.rsa.cryptoj.samples.crypto; // Import the JSAFE classes. import com.rsa.jsafe.CryptoJ; import com.rsa.jsafe.JSAFE_Recode; import com.rsa.jsafe.JSAFE_SecureRandom; import java.util.Date; import java.io.PrintStream; import java.security.SecureRandom; public class Recode extends AppApplet { private Thread thisThread = null; public void init () { super.init (); thisThread = new Thread (this); thisThread.start (); } public static void main (String[] args) throws Exception { Recode recoder = new Recode(); recoder.setApplet (false); recoder.go(); } public void go () throws Exception { JSAFE_Recode recoder = null; JSAFE_Recode decoder = null; JSAFE_SecureRandom random = null; SecureRandom seedGenerator = null; byte[] dataToEncode = null; byte[] encodedData = null; byte[] decodedData = null; int outputSize, outputLenUpdate, outputLenFinal, outputLenTotal; try { println ("Crypto-J Base64 Recode Example."); // When using a FIPS 140 compliant version of the toolkit, // check that the required power-up self-tests passed // before proceeding. if (CryptoJ.isFIPS140Compliant() && !CryptoJ.selfTestPassed()) { println("Crypto-J is disabled, power-up self-testing failed"); return; } // Initialize a random algorithm object and seed it. random = (JSAFE_SecureRandom) JSAFE_SecureRandom.getInstance ("SHA1Random", "Java"); // Seeding is the most important aspect of dealing with a secure // random number generator. It is extremely important that you seed // the PRNG with a value that contains sufficient entropy. The // following example uses a seed generator. This is the same // seed generator that Crypto-J uses when it needs to autoseed. seedGenerator = CryptoJ.getSeeder(); byte[] seed = seedGenerator.getSeed(20); random.setSeed(seed); dataToEncode = new byte [160]; random.generateRandomBytes (dataToEncode, 0, dataToEncode.length); println ("Data to recode:"); printBuffer (dataToEncode); println ("Recoding data...\n"); recoder = JSAFE_Recode.getInstance ("Base64-64", "Java"); recoder.encodeInit(); // Allocate space for the encoded data. outputSize = recoder.getOutputBufferSize(dataToEncode.length); encodedData = new byte [outputSize]; outputLenUpdate = recoder.encodeUpdate (dataToEncode, 0, dataToEncode.length, encodedData, 0); outputLenFinal = recoder.encodeFinal (encodedData, outputLenUpdate); String encodedDataString = new String (encodedData); byte[] newEncodedData = new byte [outputSize]; newEncodedData = encodedDataString.getBytes(); outputLenTotal = outputLenUpdate + outputLenFinal; println ("Base64-encoded data (" + outputLenTotal + " bytes):"); printBufferAsASCII (newEncodedData, outputLenTotal); decoder = JSAFE_Recode.getInstance ("Base64-64", "Java"); decoder.decodeInit(); // Allocate space for the decoded data. outputSize = decoder.getOutputBufferSize (newEncodedData.length); decodedData = new byte [outputSize]; outputLenUpdate = decoder.decodeUpdate (newEncodedData, 0, outputLenTotal, decodedData, 0); outputLenFinal = decoder.decodeFinal (decodedData, outputLenUpdate); outputLenTotal = outputLenUpdate + outputLenFinal; println ("Base64-decoded data (" + outputLenTotal + " bytes):"); printBuffer (decodedData, outputLenTotal); recoder.clearSensitiveData(); decoder.clearSensitiveData(); random.clearSensitiveData(); if (compareBuffers (dataToEncode, decodedData, 160)) { println("Successful Ending."); } else { println("Failure: Decoded data does not match original data."); throw new Exception("Failure: Decoded data does not match original data."); } } catch (Exception anyException) { anyException.printStackTrace (new PrintStream (this.getOutputStream ())); throw anyException; } } // Compare the first length bytes in two buffers, returning false // if something doesn't match. private static boolean compareBuffers (byte[] bufferA, byte[] bufferB, int length) { for (int i = 0 ; i < length ; i++) { if (bufferA[i] != bufferB[i]) return (false); } return (true); } // Print the data in byteArray straight to the System.out stream. private void printBufferAsASCII (byte[] byteArray, int arrayLen) { for (int i = 0 ; i < arrayLen ; i++) { print (String.valueOf((char)byteArray[i]),false); } } private void printBufferAsASCII (byte[] byteArray) { printBufferAsASCII (byteArray, byteArray.length); } }