cstmt.execute( );
cstmt.close( );
conn.close( );
System.out.println(greeting);
}
}
Compile the program and load its class file into the database by executing loadjava as follows:
loadjava -v -t -user scott/tiger@dssw2k01:1521:orcl
TestDbmsJavaSetOutput.class
This time, we'll publish the Java stored procedure using SQL*Plus. So log into the database using
SQL*Plus and execute the following SQL statement to publish TestDbmsJavaSetOutput:
create or replace procedure TDJSO_main(driver_type varchar2)
as language java
name 'TestDbmsJavaSetOutput.main(java.lang.String[])';
This SQL statement creates a procedure: TDJSO_main(driver_type varchar2). Next, turn
on the SYS.DBMS_OUTPUT.PUT_LINE buffer for SQL*Plus by executing the following
command:
SQL> set serveroutput on size 10000;
Then execute TDJSO_main, passing it the string kprb in order to specify the internal driver type
by executing the following command at the SQL*Plus prompt:
SQL> execute TDJSO_main('kprb');
Hello Scott!
PL/SQL procedure successfully completed.
You can find more information about Java stored procedures in the Java Stored Procedures
Developer's Guide available on the OTN. You can find additional information about EJB in the
Enterprise JavaBeans and CORBA Developer's Guide, also available on the OTN, or in
Enterprise JavaBeans by Richard Monson-Haefel (O'Reilly).
Now that you know how to connect internal objects to the database using JDBC, let's move on to
the next chapter where we'll examine advanced security issues such as authentication, data
encryption, and data integrity.
Chapter 6. Oracle Advanced Security
So far, we have been discussing how to make connections to an Oracle database from
applications, applets, servlets, and internal objects . All these connections have had something in
common: they were all unsecured connections. With unsecured connections, someone intent on
malicious activity can intercept the information being passed between your client and server and
even modify it while in transit. Practically speaking, if you're using your application on a corporate
intranet, this should not be much of a concern. However, if you're using JDBC to connect to a
database over the Internet, the Oracle Advanced Security (ASO) option can protect your data's
privacy and integrity.
Oracle Advanced Security is a set of advanced security options, some of which are packaged
with Oracle Enterprise Edition, and some of which are purchased from a third party. They allow
you to create a secured connection to a database or use a more secure authentication scheme.
Oracle Advanced Security provides five security enhancements to JDBC connections:
• Improved authentication using third-party authentication
• Single sign-on using third-party authentication
• Data privacy using encryption
• Data integrity using message digests
• Improved authorization using the Distributed Computing Environment (DCE)
When using the OCI driver, all five of these enhancements are enabled by configuration settings
in the Oracle Client software. However, with the Thin driver, none of the authentication and
authorization enhancements are available. As for data privacy and integrity, the configuration
settings for these are sent to the Thin driver by using a properties object with getConnection(
). So of the five security enhancements, only data privacy and integrity with the use of the Thin
driver are a concern for a programmer. Even so, let's start our discussion with authentication.
6.1 Authentication
The most common form of authentication, that is, proving that you are who you say you are, is
passwords. The OCI and Thin drivers implement the Oracle O3LOGON challenge-response
protocol. This requires a username and password. The OCI driver also supports third-party
authentication protocols such as Kerberos, RADIUS, or SecurID. However, the Thin driver
supports only O3LOGON. Nonetheless, it may be helpful to understand why third-party
authentication is needed in the first place. So let's take a look at the weaknesses of using
passwords.
The level of authentication security for a given username is equal to the effort involved in
guessing the user's password. Keeping that in mind, let's consider how people typically approach
password management.
Most people use easy-to-remember passwords, something they are familiar with, such as a family
member's name or a significant date or number. All of these are available to someone with
malicious intent, given a little effort. So all of these are easy-to-guess passwords, which provide a
low level of security.
To improve security, a person may decide to use a more complex password. But in doing so, he
may also make one of two related decisions that compromise security. First, he may decide to
use the same password everywhere. This exposes him to the risk that if the password is
guessed, a malicious user may use it to get access to all of his systems.
Another related problem is when someone in the password management facility at one site uses
another user's password stored at his site to gain access to that user's resources at another site.
From this second scenario, you can see that using the same password at every site is a
significant security risk.
A third problem with passwords is that, to improve security, a user may decide to use a different
complex password at every site. But he may then defeat that decision by writing them down to
remember them.
The third-party authentication services provided by Oracle Advanced Security addresses these
password weaknesses in various ways. If your Java program, such as an application or servlet,
can utilize the OCI driver, you can use third-party authentication to improve your system's
security. If you're using the Thin driver, you should remain hopeful, as I am, that the third-party
authentication services will be available in a future release of the product.
6.2 Data Encryption
Simply stated, data encryption equates to data privacy. A malicious user can use a network
sniffer to eavesdrop on network traffic. Without encryption, she can collect the network data in a
readable form as it is transmitted. If the data is encrypted using the RSA or DES cryptographic
algorithms, it can still be collected, but it will be unreadable. Data encryption must be enabled, or
requested, by both the client and the server for it to be used when a new connection is created.
6.2.1 Enabling Encryption on a Server
To enable data encryption on the server, you need to set the SQLNET.ENCRYPTION_SERVER
and SQLNET.ENCRYPTION_TYPES_SERVER parameters in your server's sqlnet.ora file. The
syntax for setting these parameters is:
SQLNET.ENCRYPTION_SERVER = [REJECTED | ACCEPTED | REQUESTED | REQUIRED]
SQLNET.ENCRYPTION_TYPES_SERVER = (type[,type...])
type ::= [DES40 | RC4_40 | DES | RC4_56 | RC4_128]
which breaks down as:
SQLNET.ENCRYPTION_SERVER
Specifies the server's preference for whether encryption is used when new connections
are made. The following are valid values:
REJECTED
The server does not support encryption. Connections from clients requesting encryption
will be refused.
ACCEPTED
The server will accept a request from the client to support encryption.
REQUESTED
The server will request encryption from the client.
REQUIRED
The server requires encryption. If the client cannot support encryption, then the
connection will be refused.
SQLNET.ENCRYPTION_TYPES_SERVER
Specifies the type, or types, of encryption that the server supports. Since you can specify
more than one value for this parameter, a value on the left takes precedence to a value
on the right during connection negotiation. You can choose from among one or more of
the following:
DES40
Provides 40-bit DES encryption.
RC4_40
Provides 40-bit RSA encryption.
DES
Provides 56-bit DES encryption.
RC4_56
Provides 40-bit RSA encryption.
RC4_128
Provides 128-bit RSA encryption. This is not available in Oracle software exported
outside the U.S.
For example, if you wish to require the use of encryption for all connections to your server and
support RC4_128 and RC4_56, place the following two lines in your server's sqlnet.ora file:
SQLNET.ENCRYPTION_SERVER = REQUIRED
SQLNET.ENCRYPTION_TYPES_SERVER = (RC4_128,RC4_56)
6.2.2 Enabling Encryption on a Client
How you enable encryption from the client depends on whether you are using the OCI driver or
the Thin driver. If you are using the OCI driver, the following properties must be set in the
sqlnet.ora file on the client:
SQLNET.ENCRYPTION_CLIENT = [REJECTED | ACCEPTED | REQUESTED | REQUIRED]
SQLNET.ENCRYPTION_TYPES_CLIENT = (type[,type...])
type := [DES40 | RC4_40 | DES | RC4_56 | RC4_128]
The meanings of these parameters and their settings are the same as they are for the
corresponding server-side parameters. If you are using the Thin driver and want to use
encryption, set the following properties in a Java Properties object passed to
getConnection( ):
oracle.net.encryption_client
Specifies the client's encryption preference and can take on one of the following values:
REJECTED
ACCEPTED
REQUESTED
REQUIRED
oracle.net.encryption_types_client
Specifies the type of encryption requested and can take on one or more of the following
values in a comma-delimited list. The list must be enclosed within parentheses. The
possible values are:
DES40C
Provides 40-bit DES encryption
RC4_40
Provides 40-bit RSA encryption
DES56C
Provides 56-bit DES encryption
RC4_56
Provides 56-bit RSA encryption
The next two sections talk in more detail about the process of negotiating both the use of
encryption and the type of encryption to be used. In addition, you'll find a detailed example later in
this chapter in Section 6.4.
6.2.3 Negotiating the Use of Encryption
During the process of establishing a connection between a client and a server, the server
negotiates with the client to establish whether to activate encryption. The combination of the
client-side and server-side encryption settings determines the outcome of the negotiation during a
connection. Table 6-1 shows the outcome of the various combinations. For example, if a client's
setting is REQUESTED, and the server's is ACCEPTED, then a secured connection will be
created. However, if a client's setting is ACCEPTED and so is the server's, then the connection
will be successful, but the encryption will be off. At least one side must request encryption while
the other at least accepts it in order for encryption to be activated.
Table 6-1. Connection settings for encryption and integrity
Server:
REJECTED
Server:
ACCEPTED
Server:
REQUESTED
Server:
REQUIRED
Client: REJECTED Off Off Off Fails
Client:
ACCEPTED
Off Off On On
Client:
REQUESTED
Off On On On
Client: REQUIRED Fails On On On
6.2.4 Negotiating the Type of Encryption
Assuming that a request for a secured connection is accepted, a second set of properties must
be set to allow the type of encryption to be negotiated. On the server side,
SQLNET.ENCRYPTION_TYPES_SERVER must be set to include one or more encryption types.
Accordingly, on the client side, and if you are using the OCI driver,
SQLNET.ENCRYPTION_TYPES_CLIENT must be set. If you are using the Thin driver on the
client side, you must set the property oracle.net.encryption_types_client in a Java
Properties object. You must then pass that Properties object to the Thin driver during a call
to the getConnection( ) method.
The values for the ENCRYPTION_TYPES properties specified in the sqlnet.ora file on both client
and server consist of a list of one or more encryption types separated by commas and enclosed
within parentheses. For example:
SQLNET.ENCRYPTION_TYPES_SERVER = (RC4_128,RC4_56)
The priority of which algorithm to use is determined from left to right in the list. So you should
specify the most desirable algorithm first, and then the second most desirable, and so on. During
the negotiation process, the server will select the most desirable match between the client and
server encryption types lists.
The Thin driver property oracle.net.encryption_types_client also requires that you
enclose the encryption algorithm within parentheses but supports only the selection of one
algorithm at this time. The parentheses exist for compatibility with a future release that will allow
you to specify more than one encryption algorithm. In addition, due to export regulations, the Thin
driver, which is the same set of class files for both import and export editions of the software,
does not support RC4_128 (128-bit) encryption. Also, note that the literal value for specifying
DES is different for the Thin driver than for its OCI counterpart. Don't make the mistake of
specifying "DES40" or "DES" instead of "DES40C" or "DES56C" and then pull your hair out
because it doesn't work.
As an example of how the type of encryption is negotiated, consider the case in which a server's
setting is:
SQLNET.ENCRYPTION_TYPES_SERVER = (RC4_128,RC4_56)
Then assume a client is using the Thin driver with these settings:
Properties prop = new Properties( );
prop.setProperty("user", "scott");
prop.setProperty("password", "tiger");