Section 4.4. Key Management in Oracle Database 10g


4.4. Key Management in Oracle Database 10g

You've learned the basics of how to use encryption and decryption, as well as how to generate keys. But that's the easy part; for the most part, we've simply used Oracle's supplied programs and built wrappers around them to get the job done. Now comes the more challenging aspect of the encryption infrastructuremanaging the key. Our applications will need to have access to the key to decrypt the encrypted values, and this access mechanism should be as simple as possible. On the other hand, the key should not be so simple as to be accessible to hackers. A proper key management system balances the simplicity of key access against prevention of unauthorized access to the keys.

There are essentially three different types of key management:

  • A single key for the entire database

  • A different key for each row of tables with encrypted data

  • A combination approach

The following sections describe these different approaches to key management.

The discussions in this chapter use features of Oracle Database 10g, but the concepts apply equally well to Oracle9i Database, so if you are still using that version, you will still find this section helpful.


4.4.1. Using a Single Key

With this approach, a single key is used to access any data in the database. As shown in Figure 4-3, the encryption routine reads only one key from the key location and encrypts all the data that needs to be protected. This key could be stored in a variety of locations:


In the database

This is the simplest strategy of all. The key is stored in a relational table, perhaps in a schema used specifically for this purpose. Because the key is inside the database, it is automatically backed up as a part of the database; older values can be obtained by flashback queries or the database, and the key is not vulnerable to theft from the operating system. The simplicity of this approach is also its weakness: because the key is just data in a table, anyone with the authority to modify that table (such as any DBA) could alter the key and disrupt the encryption infrastructure.


In the filesystem

The key is stored in a file, which may then be read by the encryption procedure, using the UTL_FILE built-in package. By setting the appropriate privileges on that file, you can ensure that it cannot be changed from within the database.


On some removable media controlled by the end user

This approach is the safest one; no one except the end user can decrypt the values or alter the key, not even the DBA or system administrator. Examples of removable media include a USB stick, a DVD, and a removable hard drive. A major disadvantage of removable media is the possibility of key loss or key theft. The responsibility of safekeeping the key lies with the end user. If the key is ever lost, the encrypted data is also lostpermanently.

The biggest advantage of using a single key is that the encryption/decryption routines will not need to select keys from tables or store them every time a record is manipulated in the base table. The result is that performance is generally better because of reduced CPU cycles and I/O operations. The biggest disadvantage of this approach is its dependence on a single point of failure. If an intruder breaks into the database and determines the key, the entire database becomes immediately vulnerable. In addition, if you want to change the key, you will need to change all of the rows in all of the tables, which may be quite an extensive task in a large database (see Figure 4-3).

Because of these disadvantages, particularly the consequences of key theft, this approach is used only infrequently. There are a few cases where it may be useful. One example is a data publication system where a key is generally used only once during transmission of data; after transmission, the key is destroyed and a new key is used for the next transmission. Such a system might be used by financial-data publication houses sending analytical data to customers or in a situation where one division of a company is sending confidential corporate data to the other divisions or to company headquarters.

4.4.2. Using a Key for Each Row

With the second approach, a different key is used for each row of a table, as shown in Figure 4-4. This approach is far more secure than the one discussed in the previous

Figure 4-3. Single database-key approach


section. Even if a thief succeeds in stealing a key, only one row will be compromised, not the entire table or the database. There are some disadvantages of this approach: the proliferation of keys makes it extremely difficult to manage them. Also, because encryption and decryption operations need to generate or retrieve a different key for each row, performance will suffer. Nevertheless, the added security provided by this approach makes it preferable in most encryption systems.

4.4.3. Using a Combined Approach

In some cases, neither of the approaches I've described so far may be suitable. Let's examine the pros and cons of the two options.

  • With the one-key approach:

    1. The key management is extremely simple. There is only one key to managecreate, access, and back up.

    2. The key can be placed in many places convenient for the applications to access.

    3. On the other hand, if the key is ever stolen, the entire database becomes vulnerable.

  • With the one-key-per-row approach:

    Figure 4-4. Single-key-per-row approach


    1. The number of keys equates to the number of rows, increasing the complexity of key managementmore data to back up, more storage, and so on.

    2. On the other hand, if a single key is stolen, only that corresponding row is compromised, not the entire database. This adds to the overall security of the system.

Clearly, neither approach is perfect, and you will have to find a middle groundthat is, choose an approach somewhere between the two approaches we've discussed. Perhaps you will use a single key per column, where the same key applies to all the rows; or a key per table regardless of the number of columns; or a key per schema; and so on. The number of keys to be managed would decrease dramatically with any of these approaches, but of course the vulnerability of the data would increase.

Let's take a look at a third approachI will adopt a combination of keys, as shown in Figure 4-5:

  • One key for each row, plus

  • A master key for the entire database

This is not the same as encrypting the encrypted value (in fact, that isn't even possible). Although I have defined one key per row, the actual key used during encryption is not the key stored for the row; it is, instead, the bitwise exclusive OR (XOR) of two valuesthe stored key and a master key. The master key can be stored in a location different from the location of the other keys, as shown in Figure 4-6. An intruder must find both keys if she is to successfully decrypt an encrypted value.

Figure 4-5. The master-key approach


Figure 4-6. Location of the master key


The built-in UTL_RAW package provides the BIT_XOR function , which I can use to perform a bitwise XOR operation . Here I'll perform a bitwise XOR for two values12345678 and 87654321.

     /* File on web: bit_xor.sql */       1  DECLARE       2     l_bitxor_val   RAW (2000);       3     l_val_1        VARCHAR2 (2000) := '12345678';       4     l_val_2        VARCHAR2 (2000) := '87654321';       5  BEGIN       6     l_bitxor_val :=       7        UTL_RAW.bit_xor (utl_i18n.string_to_raw (l_val_1, 'AL32UTF8'),       8                         utl_i18n.string_to_raw (l_val_2, 'AL32UTF8')       9                        );      10     DBMS_OUTPUT.put_line (   'Raw Val_1:     '      11                           || RAWTOHEX (utl_i18n.string_to_raw (l_val_1,      12                                                                'AL32UTF8'      13                                                               )      14                                       )      15                          );      16     DBMS_OUTPUT.put_line (   'Raw Val_2:     '      17                           || RAWTOHEX (utl_i18n.string_to_raw (l_val_2,      18                                                                'AL32UTF8'      19                                                               )      20                                       )      21                          );      22     DBMS_OUTPUT.put_line ('After bit XOR: ' || RAWTOHEX (l_bitxor_val));      23  END;

To perform a bitwise operation, I first need to convert the values to the RAW datatype, as shown in line 8, where the call to the UTL_I18N.STRING_TO_RAW function converts the value to RAW. In line 7, I call the bitwise XOR function, and at the end, I display the two input values converted to RAW, along with the XOR'ed value.

After executing the above block, I get this output:

     Raw Val_1:     3132333435363738     Raw Val_2:     3837363534333231     After bit XOR: 0905050101050509

Note how the bitwise XOR'ed value is very different from both of the input values. Using this technique, if I pull one value as the stored key for the row and the other as a master key , I can generate a different key that will be used in actual encryption. You will need both of the values, not just one, to arrive at the XOR'ed value. Thus, even someone who knows one of the values will not be able to decipher the XOR'ed value and thus get the actual encryption value.

This approach is not the same as re-encrypting the encrypted value with a different key. The DBMS_CRYPTO package does not allow you to re-encrypt an encrypted value. If you attempt to do so, you will encounter the ORA-28233 source data was previously encrypted error.


I can change my original encryption/decryption program to use this master key, as shown below. I add a new variable called l_master_key in line 6, which accepts a value from the user (the substitution variable &master_key). In lines 15 through 17, I have XOR'ed the key and the master key, which was used instead of the l_key variable as the encryption key in line 22.

     /* File on web: enc_dec_master.sql */       1  REM       2  REM Define a variable to hold the encrypted value       3  VARIABLE enc_val varchar2(2000);       4  DECLARE       5     l_key          VARCHAR2 (2000) := '1234567890123456';       6     l_master_key   VARCHAR2 (2000) := '&master_key';       7     l_in_val       VARCHAR2 (2000) := 'Confidential Data';       8     l_mod          NUMBER       9        :=   DBMS_CRYPTO.encrypt_aes128      10           + DBMS_CRYPTO.chain_cbc      11           + DBMS_CRYPTO.pad_pkcs5;      12     l_enc          RAW (2000);      13     l_enc_key      RAW (2000);      14  BEGIN      15     l_enc_key :=      16        UTL_RAW.bit_xor (utl_i18n.string_to_raw (l_key, 'AL32UTF8'),      17                         utl_i18n.string_to_raw (l_master_key, 'AL32UTF8')      18                        );      19     l_enc :=      20        DBMS_CRYPTO.encrypt (utl_i18n.string_to_raw (l_in_val, 'AL32UTF8'),      21                             l_mod,      22                             l_enc_key      23                            );      24     DBMS_OUTPUT.put_line ('Encrypted=' || l_enc);      25     :enc_val := RAWTOHEX (l_enc);      26  END;      27  /      28  DECLARE      29     l_key          VARCHAR2 (2000) := '1234567890123456';      30     l_master_key   VARCHAR2 (2000) := '&master_key';      31     l_in_val       RAW (2000)      := HEXTORAW (:enc_val);      32     l_mod          NUMBER      33        :=   DBMS_CRYPTO.encrypt_aes128      34           + DBMS_CRYPTO.chain_cbc      35           + DBMS_CRYPTO.pad_pkcs5;      36     l_dec          RAW (2000);      37     l_enc_key      RAW (2000);      38  BEGIN      39     l_enc_key :=      40        UTL_RAW.bit_xor (utl_i18n.string_to_raw (l_key, 'AL32UTF8'),      41                         utl_i18n.string_to_raw (l_master_key, 'AL32UTF8')      42                        );      43     l_dec := DBMS_CRYPTO.decrypt (l_in_val, l_mod, l_enc_key);      44     DBMS_OUTPUT.put_line ('Decrypted=' || utl_i18n.raw_to_char (l_dec));      45 END;

When I execute this block, this is what the output looks like. Note that first I supply the master key to encrypt the value, and then I provide the same master key while decrypting.

     Enter value for master_key: MasterKey0123456     old   3:     l_master_key varchar2(2000) := '&master_key';     new   3:     l_master_key varchar2(2000) := 'MasterKey0123456';     Encrypted=C2CABD4FD4952BC3ABB23BD50849D0C937D3EE6659D58A32AC69EFFD4E83F79D     PL/SQL procedure successfully completed.     Enter value for master_key: MasterKey0123456     old   3:     l_master_key varchar2(2000) := '&master_key';     new   3:     l_master_key varchar2(2000) := 'MasterKey0123456';     Decrypted=ConfidentialData     PL/SQL procedure successfully completed.

My program asked for the master key, which I supplied correctly, and the correct value came up. But what if I supply a wrong master key?

     Enter value for master_key: MasterKey0123456     old   3:     l_master_key varchar2(2000) := '&master_key';     new   3:     l_master_key varchar2(2000) := 'MasterKey';     Encrypted=C2CABD4FD4952BC3ABB23BD50849D0C937D3EE6659D58A32AC69EFFD4E83F79D     PL/SQL procedure successfully completed.     Enter value for master_key: MasterKey0123455     old   3:     l_master_key varchar2(2000) := '&master_key';     new   3:     l_master_key varchar2(2000) := 'WrongMasterKey';     declare     *     ERROR at line 1:     ORA-28817: PL/SQL function returned an error.     ORA-06512: at "SYS.DBMS_CRYPTO_FFI", line 67     ORA-06512: at "SYS.DBMS_CRYPTO", line 41     ORA-06512: at line 15

Note the error here: the use of a wrong master key did not expose the encrypted data. This enhanced security mechanism relies on two different keys, and both keys must be present to successfully decrypt it. If you hide the master key, it will be enough to prevent unauthorized decryption.

Because the master key is stored with the client, and it is sent over the network, a potential attacker could use a tool to "sniff" the value as it passes by. To prevent this from occurring, you can use a variety of approaches:

  • You could create a virtual local area network (VLAN) between the application server and the database server. The VLAN protects the network traffic between the servers to a great extent.

  • You could modify the master key in some predetermined way, such as by reversing the characters so that an attacker could potentially get the master key that passed over the network, but not the master key actually used.

  • Finally, for a really secure solution, you could use Oracle Advanced Security (an extra-cost option) to secure the network traffic between the client and the server.

There is no perfect key-management solution. The approach you choose will be determined by the nature of your application and your best attempts to balance security against ease of access. The three approaches described in the previous sections represent three major types of key-management techniques and are intended to give you a jump start on figuring out your own key management approach. You might very well come up with a better idea that could be more appropriate to your specific situation. For example, you might consider a hybrid approach, such as using different keys for critical tables.

Protection from the DBA?

Do you need to protect the encrypted data from your own DBA? It's a question that is bound to come up while designing the system, so you will have to address it one way or the other.

A key is stored either in the database or the filesystem. If the key store is the database, thenbecause the DBA is authorized to select from any table (including the table where the keys are stored)he can therefore decrypt any encrypted data. If the key store is the filesystem, it has to be available to the Oracle software owner so that it may be read using UTL_FILE, which the DBA may have access to. Thus, either way, protecting encrypted data from the DBA is probably a fruitless exercise. Is that an acceptable risk in your organization? The answer depends upon your organization's security policies and guidelines. In many cases, the risk is managed by placing trust in the DBA, so this may be a moot point. But in other cases, the encrypted data must be protected even from the DBA.

The only solution in that case is to store the keys on a location that the DBA will not be able to accesssuch as on the application server. But doing so makes key management difficult. You will have to ensure that the keys are backed up and protected from theft.

You can use a more complex system for key management using the master key approach described above. The master key may be placed in a digital wallet, and the application server can request the key every time it needs to encrypt and decrypt the data. Although this makes the key inaccessible to the DBA, it also makes the system complex and increases processing time.

If your objective is to prevent the DBA from altering the key, yet you want her to still be able to see it, you can use the same master-key approach. The master key can be placed in a filesystem that is read-only but accessible to the Oracle software owner to read it. This enables the database (and the DBA) to use it in encryption, but the DBA will not be able to alter it.

To keep your system manageable, especially if you want to make sure that your applications are minimally affected, then you will have to make the keys available to the Oracle software owner, either in a filesystem or inside the database in a table. In that case, it will be impossible to hide them from a DBA.





Oracle PL(s)SQL For DBAs
Oracle PL(s)SQL For DBAs
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 122

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net