X

Best Practices from Oracle Development's A‑Team

Masking Sensitive Data with Oracle GoldenGate

Introduction

At any given time, organizations are gathering, storing, and transferring millions of records about their customers across multiple enterprise environments. There are various operational settings within Oracle GoldenGate (OGG) that should be set to ensure Personally Identifiable Information (PII), or Sensitive Personal Information (SPI) is not compromised.

This article will discuss OGG configuration settings you should employ when replicating data to ensure compliance with regulatory requirements such as Sarbanes-Oxley, PCI DSS, and HIPAA.

Main Article

What is PII/SPI data?

Simply put, PII and SPI is any information that can be used to uniquely identify, contact, or locate an individual; or can be used with other sources to uniquely identify a person.

PII/SPI data consists of a broad range of information that can identify individuals, such as birth dates, addresses, driver’s license numbers, credit card numbers, bank account numbers, and much more.

The Oracle Data Masking Best Practices white paper, details how to go about identifying and masking sensitive data within a database; therefore, we are not going to discuss that here, and shall concentrate on data replication security and data masking techniques.

 Oracle GoldenGate Data Security Options

To demonstrate OGG's built-in security options, let's replicate some data for a simple order-entry payments table. Our demo table in the source and target Oracle Database is defined as:

CREATE TABLE ORDERS_PAYMENT (
ORDERS_ID NUMBER(11,0) NOT NULL
, CUSTOMERS_ID NUMBER(11,0) NOT NULL
, PAYMENT_METHOD VARCHAR2(255) NOT NULL
, PAYMENT_AMOUNT DECIMAL(11,2) NOT NULL
, CC_TYPE VARCHAR2(20)
, CC_OWNER VARCHAR2(255)
, CC_NUMBER VARCHAR2(32)
, CC_EXPIRES VARCHAR2(4)
, CC_CVV NUMBER(10,0)
, CONSTRAINT ORDERS_PAYMENT_PK PRIMARY KEY
(
ORDERS_ID
, CUSTOMERS_ID
)
ENABLE
);

In our ORDERS_PAYMENT table, it is fairly obvious that we want to protect any credit card information from prying eyes; however, let's make things a little more difficult and say our application accepts electronic funds transfers (EFT) payments and records the payment details in the PAYMENT_METHOD column. We definitely want to protect that data as it is replicated.

Typical OGG Settings

By default, OGG Extract, Extract Data Pump, and Replicat all have their security features disabled. So, an "out of the box" configuration may look like this:

Integrated Extract parameter file (eorcl.prm):
extract eorcl
userid c##ggs, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
exttrail ./dirdat/eo
logallsupcols
updaterecordformat compact
table pdborcl.tpca.*;

Extract Data Pump parameter file (porcl.prm):
extract porcl
rmthost 192.168.120.11, mgrport 15000
rmttrail ./dirdat/po
passthru
table pdborcl.tpca.*;

Integrated Replicat param file (rorcl.prm):
replicat rorcl
dboptions integratedparams(parallelism 2)
userid ggs@pdbamer, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
map pdborcl.tpca.*, target pdbamer.tpca.*;

Let's send a payment transaction through this configuration:

insert into orders_payment values (1,1,'Online credit card',165.20,'VISA','John J Doe','4111111111111111','0716','123');

Opening the GoldenGate Trail file created by the EORCL Integrated Extract in a text editor, we are able to clearly obtain details of the data records:

  PDBORCL.TPCA.ORDERS_PAYMENT D á0@  Û        
            @  ­   I 7  ORDERS_ID †        
        ÿÿÿÿ          #                L : CUSTOMERS_ID †           
ÿÿÿÿ          #                 N < PAYMENT_METHOD @   ÿ   ÿ   ÿ           ÿÿÿÿ
           "                N < PAYMENT_AMOUNT †                  ÿÿÿÿ
   "                G 5 CC_TYPE @                   (ÿÿÿÿ            "
H 6 CC_OWNER @   ÿ   ÿ   ÿ          Bÿÿÿÿ            "                I 7  CC_NUMBER @
Fÿÿÿÿ            "                J 8 CC_EXPIRES @                   lÿÿÿÿ
"                F 4 CC_CVV †                  vÿÿÿÿ          "
Z /G H  $E A ” ÿ òW—?ݘÀ     |    † R   D  ”           
   Online credit card          @ˆ    VISA
John J Doe    4111111111111111    0716

Furthermore, my Extract Data Pump is sending this data over an open TCP/IP network with no security enabled. If this information is being sent outside of the enterprise production data center via a public network, it could be sniffed out.

Setting OGG Trail Security

The OGG Extract parameter ENCRYPTTRAIL is used to encrypt data written to the GoldenGate Trails. ENCRYPTTRAIL supports the following encryption methods:

  • Master key and wallet method: Generate an one-time AES key for each trail file and uses it to encrypt the contents. Then, the one-time key is encrypted by the master-key and stored in the trail file header.
  • ENCKEYS method: Generate an AES encryption key, store it under a given name in an ENCKEYS file, and configure Oracle GoldenGate to use that key to directly encrypt or decrypt the contents of the trail file.
  • Default method: ENCRYPTTRAIL without options specifies 256-key byte substitution AES256 encryption.

The master key and wallet encryption method is best practice, and the most secure encryption method. The default method is the least secure of the three encryption methods.

Be sure to review the applicable Oracle GoldenGate documentation before enabling Trail encryption.

Setting ENCRYPTTRAIL in my Integrated Extract, EORCL, will result in all downstream Trail data being encrypted. This means that the Trail created by the Extract Data Pump, PORCL, will also be encrypted without having to explicitly set the parameter in that Extract.

My Integrated Extract parameter file now looks like this (note that I am using the least secure encryption setting. The best practice encryption method you should employ is master key and wallet):

extract eorcl
userid c##ggs, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
encrypttrail
exttrail ./dirdat/eo
logallsupcols
updaterecordformat compact
table pdborcl.tpca.*;

Let's send another payment record through the replication stream and see what happens.

insert into orders_payment values (2,1,'Online credit card',19.99,'AMEX','John J Doe','378282246310005','0716','1234');

Now when I open either of the Trail files with a text editor, the contents are indecipherable.

 ph˜lˆ ƒhl{²3ÜœÃñ}Eƒ ó a ÊkH@ºx ÿ³©ŠfSI[R5‹ipÝ
„…Àߟ:¬NÜÖ !.!ÔËw㞈èÏ;:7¤'ap^Pd›@§‡¬ e9œb7à! Ã_Tm«Š>ù™…‰h  J!¾’fÈ
À7–#b€Ül ñMø• @eçc ,«¯´š€}rhN fSI"øq[†’0y,”;ïí¬€Œ 6n‹.ÔèE*ñ$%)Õû¼­å ¢ÒŸ‘†
¯9¼‘•t[ £o½†~zž?›-ÒÓwXDž© uÃAJBølg­©g‡æØbã'œ`¦MøÎ óÜacSñHÿõÛÁ¾r©NŠÂS(x4ÌúɍºÏ…]”oí÷PÜÖ
n&´!0 Úé¤GèŽ| xƒ…‡oŸá½Kðò‡IÌ5ìçd7à!\LåT,æíî¸X…H©O|gp Ùý¿xÄ 73Ø23'l ¸ME

But what about my Replicat? Do I need to do anything at the target?

In this case, no. There is a parameter DECRYPTTRAIL that must be set in the Replicat only when the ENCKEYS encryption method is used.

Setting Data Transmission Security

When Extract Data Pump is sending data over a public or non-secure network, it is best practice to set the RMTHOST ENCRYPT parameter option. The option format is:

ENCRYPT algorithm [KEYNAME key_name]

The following encryption options are supported:

  • Master key and wallet method: Generate a session key based on the active master key and algorithm specified.
  • ENCKEYS method: Generate an AES encryption key, store it under a given name in an ENCKEYS file, and configure Oracle GoldenGate to use that key to encrypt the data.

Be sure to review the applicable Oracle GoldenGate documentation before enabling data stream encryption.

Master key and wallet is the best practice method for encrypting the data stream; however, I am going to use the ENCKEYS method for this discussion.

To enable the ENCKEYS method for data stream encryption, run the keygen utility to create an AES256 bit key inside of a file named ENCKEYS.

D:\app\ogg>keygen 256 1 > ENCKEYS

Then edit the ENCKEYS file, give the key a name, save the file, and place a copy in the target server's GOLDENGATE_HOME directory (the directory where the OGG object files are installed). In the ENCKEYS file the key name is the text at the beginning of the line, followed by a space, and then the encryption key. The key name can be any alphanumeric text, I could have named this key "SecureKey256", "mybighexkey", "FRED", or some other combination of letters and numbers.

ninh 0x7BABF229E118F101A5125518FB878164B09ACC36D257C72EC116204FEA021157

Then modify the Extract Data Pump configuration and bounce the process:

extract porcl
rmthost 192.168.120.11, mgrport 15000, encrypt AES256, keyname ninh
rmttrail ./dirdat/po
passthru
table pdborcl.tpca.*;

The source to target data steam is now encrypted.

Masking Data In Development Databases

Most organizations copy production data to development servers so developers and quality assurance personnel can debug, patch, and test applications. In this case, we want to provide a means for obfuscating sensitive data while maintaining usability for debugging and testing.

To make this change during replication, we'll use OGG Column Conversion Functions to convert the sensitive customer data to dummy test data. To maintain the secure data replication stream this needs to be done in the Extract Data Pump before the data is transmitted out of our production data center.

You are probably asking yourself why this needs to be done in the Extract Data Pump if the OGG Trail and data stream are already encrypted.

To answer that question, lets open the encrypted trail we created earlier with the Oracle GoldenGate Logdump utility to see if we can find Mr. Doe's AMEX transaction.

Logdump 102> open ./dirdat/po000000005
Logdump 103> ghdr on
Logdump 104> decrypt on
Logdump 105> detail data
Logdump 106> filter inc string /AMEX/
Logdump 106> n
Name: PDBORCL.TPCA.ORDERS_PAYMENT  (TDR Index: 2)
After  Image:                                             Partition 12   G s
0000 000a 0000 0000 0000 0000 0002 0001 000a 0000 | ....................
0000 0000 0000 0001 0002 0016 0000 0012 4f6e 6c69 | ................Onli
6e65 2063 7265 6469 7420 6361 7264 0003 000a 0000 | ne credit card......
0000 0000 0000 07cf 0004 0008 0000 0004 414d 4558 | ................AMEX
0005 000e 0000 000a 4a6f 686e 204a 2044 6f65 0006 | ........John J Doe..
0013 0000 000f 3337 3832 3832 3234 3633 3130 3030 | ......37828224631000
3500 0700 0800 0000 0430 3731 3600 0800 0a00 0000 | 5........0716.......
Column     0 (x0000), Len    10 (x000a)
0000 0000 0000 0000 0002                          | ..........
Column     1 (x0001), Len    10 (x000a)
0000 0000 0000 0000 0001                          | ..........
Column     2 (x0002), Len    22 (x0016)
0000 0012 4f6e 6c69 6e65 2063 7265 6469 7420 6361 | ....Online credit ca
7264                                              | rd
Column     3 (x0003), Len    10 (x000a)
0000 0000 0000 0000 07cf                          | ..........
Column     4 (x0004), Len     8 (x0008)
0000 0004 414d 4558                               | ....AMEX
Column     5 (x0005), Len    14 (x000e)
0000 000a 4a6f 686e 204a 2044 6f65                | ....John J Doe
Column     6 (x0006), Len    19 (x0013)
0000 000f 3337 3832 3832 3234 3633 3130 3030 35   | ....378282246310005
Column     7 (x0007), Len     8 (x0008)
0000 0004 3037 3136                               | ....0716
Column     8 (x0008), Len    10 (x000a)
0000 0000 0000 0000 04d2                          | ..........

As you may see from the sample output above, Logdump has the ability to decrypt Trails, so we need to ensure our sensitive customer data is altered before being sent to the development server.

Extract Data Pump Changes

For review, here is our payment table definition again:

CREATE TABLE ORDERS_PAYMENT (
ORDERS_ID NUMBER(11,0) NOT NULL
, CUSTOMERS_ID NUMBER(11,0) NOT NULL
, PAYMENT_METHOD VARCHAR2(255) NOT NULL
, PAYMENT_AMOUNT DECIMAL(11,2) NOT NULL
, CC_TYPE VARCHAR2(20)
, CC_OWNER VARCHAR2(255)
, CC_NUMBER VARCHAR2(32)
, CC_EXPIRES VARCHAR2(4)
, CC_CVV NUMBER(10,0)
, CONSTRAINT ORDERS_PAYMENT_PK PRIMARY KEY
(
ORDERS_ID
, CUSTOMERS_ID
)
ENABLE
);

For data being replicated to my development server, I am going to mask all production data for the CC_OWNER and CC_NUMBER columns if they are present and not null. Furthermore, CC_NUMBER is going to be changed to a test credit card number as specified by the credit card issuer. This will allow me to maintain usability of the data for troubleshooting and testing.

For CC_OWNER, if the column is present and not null, we will do a blanket change of the data to "J Q Public".

Remember, our application also accepts EFT payments, we need to determine when and how to mask the data in the PAYMENTS_METHOD column. Upon review of my application design documentation, I was able to determine that EFT payments are recorded in PAYMENTS_METHODS like this:

"EFT Routing Number: [bank routing number] Account Number: [customer account number] EFT Code: [return code]".

Now we know what to mask in the data stream so lets reconfigure our Extract Data Pump.

Because the Extract Data Pump will be doing real-time manipulations we need to make a couple of generic changes:

  • Remove the PASSTHRU parameter.
  • Add the database connection credentials for the OGG database user.
  • Decrypt the Trail data being read by the Extract Data Pump.
  • Encrypt the Trail data being written by the Extract Data Pump.

With these changes in place, my Extract Data Pump parameter file now looks like this:

extract porcl
decrypttrail
userid c##ggs, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
rmthost 192.168.120.11, mgrport 15000, encrypt AES256, keyname ninh
encrypttrail
rmttrail ./dirdat/po
table pdborcl.tpca.*;

Now we can begin working on the data masking. We will tackle the credit card data first.

In OGG, the parameter option COLMAP allows us to manipulate columnar data. In the Extract Data Pump, I add a TABLE statement that contains the TARGET and COLMAP options like this:

TABLE pdborcl.tpca.orders_payment, TARGET pdborcl.tpca.orders_payment,
COLMAP (USEDEFAULTS,
CC_OWNER = @IF (@COLTEST (CC_OWNER, PRESENT),
             'J Q Public', @COLSTAT(NULL))
);

This statement is telling Extract Data Pump to take all incoming data for the ORDERS_PAYMENT table and change it according to the settings of COLMAP. This modified data is then written to the Extract Data Pump's Trail in lieu of the original ORDERS_PAYMENT data.

In the COLMAP clause, USEDEFAULTS tells Extract Data Pump to pass through any data not explicitly mapped to a column. So in the above example, the only data being changed by Extract Data Pump is for the CC_OWNER column; all other data is written to the output stream exactly as it was captured from the source database.

For CC_OWNER we are using three OGG Column Conversion Functions @IF, @COLTEST, and @COLSTAT. This column mapping statement is doing the following:

  • Check the Trail record being processed by Extract Data Pump to determine if the CC_OWNER column is present and not null.
  • If the record contains a customer name (present and not null), change the value of this record to "J Q Public".
  • If the record is not present or is null, set the outgoing value to NULL.

Let's run a quick test to validate this configuration.

Source transaction:

insert into orders_payment values (10,10,'Online credit card',59.99,'MasterCard','Fiona Page','5555555555554444','0516','890');

Source database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
10 10 Online credit card 59.99
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
MasterCard Fiona Page 5555555555554444 0516 890

 

Target database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
10 10 Online credit card 59.99
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
MasterCard J Q Public 5555555555554444 0516 890

 

For the CC_NUMBER data, I want to replace the customer's real credit card number with test numbers published by the issuers. This allows our developers and testers to perform real-world simulations on the payment data. One way of doing this is via this COLMAP:

CC_NUMBER = @CASE (CC_TYPE,
              'AMEX', '378282246310005',
              'Discover', '6011111111111117',
              'MasterCard', '5105105105105100',
              'Visa', '4012888888881881',
              @COLSTAT(NULL))

Here we are using two OGG Column Conversion Functions to manipulate the incoming data, @CASE and @COLSTAT.

This @CASE function statement looks confusing, but is actually very easy to understand.

In this example, Extract Data Pump is checking the value of the CC_TYPE column in its read (incoming) data stream. If the value of CC_TYPE matches any of the credit card names specified, the value in the write (outgoing) data stream value for CC_NUMBER is replaced with the credit card number defined for that card.

If the CC_TYPE column is not present in the incoming data stream, is null, or contains text not defined in our @CASE statement, we are going to set the write (outgoing) data stream value for CC_NUMBER to NULL.

This is just one way of converting the CC_NUMBER data.

Instead of using @CASE, we could have just done a global replacement:

CC_NUMBER = @IF (@COLTEST (CC_NUMBER, PRESENT),
              '1111222233334444', @COLSTAT(NULL))

Or used different OGG Column Conversion Functions to test the incoming data and change the values in the write data stream:

CC_NUMBER = @IF (@COLTEST (CC_TYPE, PRESENT), 
                    @IF (@STREQ (CC_TYPE, 'AMEX'), '378282246310005',
                      @IF (@STREQ (CC_TYPE, 'Discover'), '6011111111111117',
                        @IF (@STREQ (CC_TYPE, 'MasterCard'), '5105105105105100',
                          @IF (@STREQ (CC_TYPE, 'Visa'), '4012888888881881',
                    @COLSTAT(NULL))

I find the @CASE statement to be cleaner and easier to understand, so am going to keep it in my parameter file and run a test with this Extract Data Pump configuration:

extract porcl
decrypttrail
userid c##ggs, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
rmthost 192.168.120.11, mgrport 15000, encrypt AES256, keyname ninh
encrypttrail
rmttrail ./dirdat/po
table pdborcl.tpca.orders_payment, target pdborcl.tpca.orders_payment,
colmap (usedefaults,
        CC_OWNER = @IF (@COLTEST (CC_OWNER, PRESENT),
                     'J Q Public', @COLSTAT(NULL)),
        CC_NUMBER = @CASE (CC_TYPE,
                      'AMEX', '378282246310005',
                      'Discover', '6011111111111117',
                      'MasterCard', '5105105105105100',
                      'Visa', '4012888888881881',
                      @COLSTAT(NULL))
);

Source transaction:

insert into orders_payment values (167,10,'Online credit card',28.20,'MasterCard','Fiona Page','5555555555554444','0516','890');

Source database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
167 10 Online credit card 28.20
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
MasterCard Fiona Page 5555555555554444 0516 890

 

Target database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
167 10 Online credit card 28.20
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
MasterCard J Q Public 5105105105105100 0516 890

 

So far, so good; we have managed mask real customer data being replicated to our development server; so let's move on to the PAYMENT_METHOD data for EFT transactions. To review, our application records this information in this format:

"EFT Routing Number: [bank routing number] Account Number: [customer account number] EFT Code: [return code]".

We could just do a global replacement of the data anytime the text "EFT" is encountered in the incoming data stream, or we could replace only the bank routing and customer account numbers.

To test the incoming data stream for the text "EFT" and perform a global data replacement, I would define my COLMAP statement like this:

PAYMENT_METHOD = @IF (@STRFIND (PAYMENT_METHOD, 'EFT ', 0) > 0,
                     'EFT Routing Number: 000000000 Account Number: 000000 EFT Code: 000',
                   PAYMENT_METHOD)

This COLMAP statement uses the @STRFIND Column Conversion Function to check the incoming PAYMENT_METHOD column for the text "EFT" followed by a space. If the text is not found zero is returned and the original data is passed through to the write data stream. If the text is found, the starting position of the text in the string is returned and the data is replaced in the write data stream with the defined replacement string.

Testing this configuration setting returns:
Source transaction:

insert into orders_payment values (197,7,'EFT Routing Number: 012345678 Account Number: 123456 EFT Code: 001',178.00,NULL,NULL,NULL,NULL,NULL);

Source database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
197 7 EFT Routing Number: 012345678 Account Number: 123456 EFT Code: 001 178
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
(null) (null) (null) (null) (null)

 

Target database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
197 7 EFT Routing Number: 000000000 Account Number: 000000 EFT Code: 000 178
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
(null) (null) (null) (null) (null)

 

If we needed to replace the routing and account number and retain the EFT code, we could define the COLMAP like this:

PAYMENT_METHOD = @IF (@STRFIND (PAYMENT_METHOD, 'EFT ', 0) > 0,
                   @STRCAT ('EFT Routing Number: 000000000 Account Number: 000000', ' ',
                        @STREXT (PAYMENT_METHOD, @STRFIND (PAYMENT_METHOD, 'EFT Code', 0),
                        @STRLEN(PAYMENT_METHOD))),
                  PAYMENT_METHOD)

Once again, this COLMAP statement uses the @STRFIND function to check the incoming PAYMENT_METHOD column for the text "EFT" followed by a space. If the text is not found zero is returned and the original data is passed through to the write data stream.

If the text is found a new string will be created using the @STRCAT function. This string will be comprised of the following elements:

  • The text 'EFT Routing Number: 000000000 Account Number: 000000'.
  • A space
  • The EFT Code from the original data.

To get the EFT Code, we will use the @STREXT function to extract the substring from the original data. For the string extraction, we use @STRFIND again to get the character offset for the starting position of "EFT Code" inside of the string and grab all text from that point to the end of the string as returned by @STRLEN.

Testing this configuration setting returns:
Source transaction:

insert into orders_payment values (222,156,'EFT Routing Number: 234567891 Account Number: 7891234 EFT Code: 061',1776.07,NULL,NULL,NULL,NULL,NULL);

Source database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
222 156 EFT Routing Number: 234567891 Account Number: 7891234 EFT Code: 061 1776.07
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
(null) (null) (null) (null) (null)

 

Target database values:

ORDERS_ID CUSTOMERS_ID PAYMENT_METHOD PAYMENT_AMOUNT
222 156 EFT Routing Number: 000000000 Account Number: 000000 EFT Code: 061 1776.07
CC_TYPE CC_OWNER CC_NUMBER CC_EXPIRES CC_CVV
(null) (null) (null) (null) (null)

 

The end result is that my Extract Data Pump parameter file looks like this:

extract porcl
decrypttrail
userid c##ggs, password AACAAAAAAAAAAAHAAIFBOIYAMCGIMARE BLOWFISH, ENCRYPTKEY DEFAULT
rmthost 192.168.120.11, mgrport 15000, encrypt AES256, keyname ninh
encrypttrail
rmttrail ./dirdat/po
table pdborcl.tpca.orders_payment,
  target pdborcl.tpca.orders_payment,
   colmap (usedefaults,
     CC_OWNER = @IF (@COLTEST (CC_OWNER, PRESENT),
                      'J Q Public', @COLSTAT(NULL)),
     CC_NUMBER = @CASE (CC_TYPE,
                  'AMEX', '378282246310005',
                  'Discover', '6011111111111117',
                  'MasterCard', '5105105105105100',
                  'Visa', '4012888888881881',
                  @COLSTAT(NULL)),
     PAYMENT_METHOD = @IF (@STRFIND (PAYMENT_METHOD, 'EFT ', 0) > 0,
                    @STRCAT ('EFT Routing Number: 000000000 Account Number: 000000', ' ',
                       @STREXT (PAYMENT_METHOD, @STRFIND (PAYMENT_METHOD, 'EFT Code', 0),
                          @STRLEN(PAYMENT_METHOD))),
                       PAYMENT_METHOD)
);

I have successfully configured the full data replication stream to ensure sensitive customer information remains secure.

Summary

In this article we explored solutions for ensuring sensitive customer information is not compromised during replication via Oracle GoldenGate by (1) encrypting the Oracle GoldenGate Trail files, (2) encrypting the TCP/IP data stream between the Extract Data Pump and the target Oracle GoldenGate instance, and (3) using Oracle GoldenGate Column Conversion Functions to obfuscate data replicated to non-production servers.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha

Recent Content