This example demonstrates a technique for encrypting data in a database. In this scenario, decrypting the data incurs a performance penalty.
Change to the following directory: samples-dir\UltraLiteJ.
For information about the default location of samples-dir, see Samples directory.
Run the following command (the command is case sensitive):
rundemo Encrypted |
This example is for Java SE. For a complete BlackBerry encryption sample, see samples-dir\UltraLiteJ\BlackBerryEncryption.
// ***************************************************** // Copyright (c) 2006-2010 iAnywhere Solutions, Inc. // Portions copyright (c) 2006-2010 Sybase, Inc. // All rights reserved. All unpublished rights reserved. // ***************************************************** // This sample code is provided AS IS, without warranty or liability // of any kind. // // You may use, reproduce, modify and distribute this sample code // without limitation, on the condition that you retain the foregoing // copyright notice and disclaimer as to the original iAnywhere code. // // ********************************************************************* package com.ianywhere.ultralitej.demo; import com.ianywhere.ultralitej12.*; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; /** * Encrypted -- sample program to demonstrate encryption of database. * * This sample requires either the Sun JDK 1.5 (or later) or a freeware * version of the Java encryption classes (JCE). */ public class Encrypted { /** Create the database. * @return connection for a new database */ private static Connection createDatabase() throws ULjException { ConfigPersistent config = DatabaseManager.createConfigurationFile( "Encrypt.ulj" ); config.setEncryption( new Encryptor() ); Connection conn = DatabaseManager.createDatabase( config ); PreparedStatement ps = conn.prepareStatement( "CREATE TABLE Product" + "( prod_no INT NOT NULL PRIMARY KEY" + ", prod_name VARCHAR(32)" + ", price NUMERIC(9,2)" + ")" ); ps.execute(); ps.close(); return conn; } /** Add a product row. * @param ri PreparedStatement for the Product table * @param prod_no product number * @param prod_name product name * @param price selling price */ private static void addProduct( PreparedStatement ri, int prod_no, String prod_name, String price ) throws ULjException { ri.set( "prod_no", prod_no ); ri.set( "prod_name", prod_name ); ri.set( "price", price ); ri.execute(); } /** Populate the database. * @param conn connection to database */ private static void populate( Connection conn ) throws ULjException { PreparedStatement ri = conn.prepareStatement( "INSERT INTO Product( prod_no, prod_name, price )" + " VALUES( :prod_no, :prod_name, :price )" ); addProduct( ri, 2001, "blue screw", ".03" ); addProduct( ri, 2002, "red screw", ".09" ); addProduct( ri, 2004, "hammer", "23.99" ); addProduct( ri, 2005, "vise", "39.99" ); ri.close(); conn.commit(); } /** Display contents of Product table. * @param conn connection to database */ private static void displayProducts( Connection conn ) throws ULjException { PreparedStatement stmt = conn.prepareStatement( "SELECT prod_no, prod_name, price FROM Product" + " ORDER BY prod_no" ); ResultSet cursor = stmt.executeQuery(); for( ; cursor.next(); ) { String prod_no = cursor.getString( 1 /* "prod_no" */ ); String prod_name = cursor.getString( "prod_name" ); //access by name String price = cursor.getString( 3 /* "price" */ ); Demo.display( prod_no + " " + prod_name + " " + price ); } cursor.close(); stmt.close(); } /** mainline for program. * @param args command-line arguments (not used) */ public static void main ( String[] args ) { try { Connection conn = createDatabase(); populate( conn ); displayProducts( conn ); conn.release(); } catch( ULjException exc ) { Demo.displayException( exc ); } } /** Class to implement encryption/decryption of the database. */ static class Encryptor implements EncryptionControl { private SecretKeySpec _key = null; private Cipher _cipher = null; /** Encrypt a page stored in the Database. * @param page_no the number of the page being encrypted * @param src the encrypted source page which was read from the Database * @param tgt the unencrypted page (filled in by method) * @param num_bytes the number of bytes to be decrypted */ public void decrypt( int page_no, byte[] src, byte[] tgt, int num_bytes ) throws ULjException { byte[] decrypted = null; try { _cipher.init( Cipher.DECRYPT_MODE, _key ); decrypted = _cipher.doFinal( src ); } catch( Exception e ) { Demo.display( "Error: decrypting" ); throw new EncryptionError(); } System.arraycopy( decrypted, 0, tgt, 0, num_bytes ); } /** Encrypt a page stored in the Database. * @param page_no the number of the page being encrypted * @param src the unencrypted source * @param tgt the encrypted target page which will be written to the Database (filled in by method) */ public void encrypt( int page_no, byte[] src, byte[] tgt ) throws ULjException { byte[] encrypted = null; try { _cipher.init( Cipher.ENCRYPT_MODE, _key ); encrypted = _cipher.doFinal( src ); } catch( Exception e ) { Demo.display( "Error: encrypting" ); throw new EncryptionError(); } System.arraycopy( encrypted, 0, tgt, 0, tgt.length ); } /** Initialize the encryption control with a password. * @param password the password */ public void initialize( String password ) throws ULjException { try { byte[] bytes = password.getBytes( "UTF8" ); MessageDigest md = MessageDigest.getInstance( "SHA" ); bytes = md.digest( bytes ); byte[] key_bytes = new byte[16]; for( int i = key_bytes.length; i > 0; ) { --i; key_bytes[ i ] = bytes[ i ]; } _key = new SecretKeySpec( key_bytes, "AES" ); _cipher = Cipher.getInstance( "AES/ECB/NoPadding" ); } catch( Exception e ) { Demo.display( "Error: initializing encryption" ); throw new EncryptionError(); } } } /** Error class for encryption errors. */ static class EncryptionError extends ULjException { /** Constructor. */ EncryptionError() { super( "Encryption Error" ); } /** * Get the error code, associated with this exception. * @return the error code (from the list at the top of this class) associated * with this exception */ public int getErrorCode() { return ULjException.SQLE_ERROR; } /** Get exception causing this exception, if it exists. * @return null, if there exists no causing exception; otherwise, the exception causing this exception */ public ULjException getCausingException() { return null; } /** Get offset of error within a SQL string. * @return (-1) when there is no SQL string associated with the error message; otherwise, * the (base 0) offset within that string where the error occurred. */ public int getSqlOffset() { return -1; } } } |
Discuss this page in DocCommentXchange.
|
Copyright © 2010, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.0 |