This example demonstrates a technique for encrypting data in a database. In this scenario, decrypting the data incurs a performance penalty.
To run the Encrypted.java exampleChange 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 |