转自:http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-1001lirm/index.html
在客户环境中,我们经常会需要对一些敏感数据进行保护,比如身份证号码、手机号码、社保编号以及电子邮件地址等等。我们可以使用加密的方式来对敏感数据进行保护,但加密的数据会存在被解密的危险。在 IBM Optim Data Privacy 解决方案中,提供了综合数据屏蔽技术,使用各种屏蔽选项,包括屏蔽字符或数字,生成随机或序列数字的技术,以及更高级的屏蔽实用程序,来支持复杂的数据隐私要求。
本文通过使用三种不同的方法,即函数转换、编写 Exit Routine 和 Column Map Procedure,以身份证数据转换为实例,全面地讲述了 IBM Optim Data Privacy 技术的使用方法,向读者介绍编写自定义数据转换规则的方法,并能够让读者对这三种方法的使用有所比较。
IBM Optim Data Privacy 解决方案提供了全面的数据屏蔽技术,以满足数据隐私遵从性需求:
在本文中,我们将贯穿身份证数据转换这个例子,向您展示如何使用 IBM Optim Data Privacy 解决方案实现数据屏蔽以及如何编写自己的数据变性规则。
本文假设您具有 Optim Data Privacy 解决方案的基本使用经验,能够完成 Optim 在 Windows 平台的安装和配置工作。
同时,配合文中的示例,需要您安装以下软件
在 DB2 数据库中创建 optimdir 和 sourcedb 数据库,如下:
create db optimdir using codeset utf-8 territory zh_CN create db sourcedb using codeset utf-8 territory zh_CN |
其中,配置 Optim 使用 optimdir 作为 Directory,并且创建 sourcedb 的数据库别名。
使用附件中提供的 Extract 文件中的数据完成示例。其中 LOOKUP_ID.XF 保存有样本数据,供哈希转换函数使用;SAMPLE_ID.XF 文件保存有待转换数据,使用该数据进行数据转换。
在 IBM Optim 中,提供了很多转换函数来帮助实现数据屏蔽,常用的函数有 RAND、SUBSTR、HASH_LOOKUP、AGE 等等。本文,我们使用 HASH_LOOKUP 作为范例说明此类函数的使用方法。
HASH_LOOKUP 函数通过哈希函数映射,将待转换列中的数据替换为样本表中的值,从而实现数据转换的功能。样本表除了需要提供一个包含样本值的列外,还需提供一个具有唯一值的整数类型的列以供哈希映射。
本文的附件 LOOKUP_ID.XF 中提供了一组身份证样本数据,该文件是 Optim Extract 文件,可以通过 Insert 功能插入到数据库当中。具体插入步骤如下。
打开 Optim,选择“Action->Insert”。在 Insert Request Editor 面板中,Source File 选择我们提供的“LOOKUP_ID.XF”文件;在 Control file 处填写 lookup.CF;Table Map Options 选择“Local”;Process Option 选择“Insert”。然后点击“Edit Table Map”按钮,如图 1 所示。
在 Table Map Editor 面板中,Qualifier 选择 SOURCEDB,creator Id 选择您自己的 schema,这里我们选择为 db2admin; 在下部的 Tables 部分,Destination Table 处填写“LOOKUP_ID”,按 Tab 键,Type 处会显示“Unknown”。选择“File->Update and Return”。如图 2 所示。
点击“Run”按钮,运行 Insert 请求。如图 3 所示。
在弹出的 Create 面板中,选择“Create all selected objects”按钮,创建目标表和主键约束。如图 4 所示。
在接下来的两个界面点击“proceed”和“continue”, 并关闭创建完成的界面后,Optim 会进行 Insert 操作。插入完成后,会显示成功,并生成操作报告。
配合本例,我们随附件同时提供了待转换的身份证信息样本,保存在“SAMPLE_ID.XF”文件中。执行同样的步骤将该文件中的数据插入到 sourcedb 中。这样就完成了样本数据的准备工作。
回到 Optim 主界面,选择“Action->Convert”。在 Convert Request Editor 主界面中,Source File 选择我们提供的“Sample_ID.XF”文件;Control File 填写 sample.CF;Destination File 填写 Convert_ID.XF;Table Map Options 选择“Local”。然后点击“Edit Table Map”按钮。
在 Table Map Editor 界面中,Qualifier 填写为 SOURCEDB.DB2ADMIN;Destination Table 填写为 SAMPLE_ID;在 Column Map or “Local”处填写“Local”,并在该处单击右键,选择“Open Column Map”。如图 6 所示。
在 source 的 ID 列的位置,填入如下内容:
HASH_LOOKUP(ID,LOOKUP(no,ID)) |
单击 TAB 键后,可以看到该行最右侧的 Status 列变为“Lookup Function”。如图 7 所示。
连续选择“File->Update and return” 保存更改,返回到 Convert Request Editor 主界面。单击“Run”执行该 Convert 请求。执行结束后将自动生成执行报告,如图 8 所示。可以看到,45 条数据全部转换成功。
回到 Optim 主界面,选择“Action->Compare”。在 Compare Request Editor 主界面的 General 标签中,Compare File 填写“ID.CMP”;选中“Browse Results Immediately”方框,以便比较结束后立即查看结果;Comparision Mode 选择“Single Table:Source File – Source File”。如图 9 所示。
在 Source 标签中,Source 1 选择 SAMPLE_ID.XF,Source 2 选择 Convert_ID.XF。然后执行 Compare 请求。如图 10 所示。
比较结束后会打开 ID.CMP 文件如下。双击表名进入比较界面。
相邻的两行为转换前后的行,可以看到他们的身份证字段已经全部进行了转换。
如果 Optim 提供的数据转换函数无法满足用户的特殊需求,我们可以通过编写 Exit Routine 来自定义数据转换规则,从而实现数据转换的高级定制。
Exit routine 提供给用户通过编程实现自定义规则的能力。Optim 提供了三种 Exit routine:
其中 Standard Exit 最为常用,我们这里也采用编写 Standard Exit 来实现身份证数据转换。
Exit Routine 的调用遵循 C 语言规范。因此,我们在附件中给出了 C 语言的示例程序,包括以下 3 个文件:
Optim 调用 Exit Routine 的接口函数 PSTColMapExit(),我们需要在该函数中完成转换规则的编写。
PSTColMapExit() 函数的定义如下:
__declspec(dllexport) short
PSTColMapExit( PST_STRUCT_CM_EXIT_PARM * pInputParms,
PST_STRUCT_CM_EXIT_COL_LIST * pSrcColList,
PST_STRUCT_CM_EXIT_COL_LIST * pDstColList )
|
pInputParms保存了当前列映射操作的信号和参数,其中 FuncCode为当前的处理信号,如果收到 PST_CM_FUNC_TERMINATE信号,则表明程序处理结束;DestColIndex为目标列在表中的排序,用于选定进行转换的列。PSrcColList为源数据列的指针,pDstColList为指向目标列的指针。
程序进行初始化和条件判断之后,首先需要获取源数据列的数据。主要代码如下:
// 得到源数据列的指针
pCol = &(pSrcColList->Col[ pInputParms->DestColIndex ]);
rc = (*pInputParms->pPSTGetColValue)// 获取源数据列数据
(pCol->hCol, // 源数据列的句柄
PST_C_CHAR, // 指明列的数据类型
0, //Precision,DECIMAL 数据类型专用,这里不需要
0, //Scale,DECIMAL 数据类型专用,这里不需要
&ID, // 保存数据的变量地址
sizeof(ID), // 变量的大小
&IndVar ); // 数据是否为空的标志,-1 为空,不空则为 0
switch ( rc )
{
case PSTEXIT_SUCCESS: // 成功
case PSTEXIT_TRUNC_WARNING: // 含有警告信息,但仍然可以继续
break;
default:
return( PST_CM_EXIT_ABORT_PROCESS );// 发生严重错误,数据转换终止
}
|
在获取了身份证数据之后,我们进行转换。变换规则为:
身份证的最后一位校验位,由以下规则计算得出:
转换部分的关键代码如下:
// 根据身份证最后四位生成随机数序列
seed=atoi(&ID[14]);
srand(seed);
// 分别获得随机生成的省号位置、出生年份和出生月份
pos[0]=rand()%31;
pos[1]=rand()%30+70;
pos[2]=rand()%12+1;
// 将数字转化为字符
itoa(pos[1],year,10);
itoa(pos[2],month,10);
// 替换省号
ID[0]=pro[2*pos[0]];
ID[1]=pro[2*pos[0]+1];
// 替换年份
ID[8]=year[0];
ID[9]=year[1];
// 替换月份
if(month[1]!='\0')
{
ID[10]=month[0];
ID[11]=month[1];
}
else
{
ID[10]='0';
ID[11]=month[0];
}
// 得到每一位身份证的整形值
for(i=0;i<17;i++)
data[i]=ID[i]-'0';
// 计算校验位
data[17]=0;
for(i=0;i<17;i++)
data[17]+=data[i]*wi[i];
// 校验位赋值
ID[17]=yi[data[17]%11];
|
最后,将变化完成的数据写到目标列中。代码如下:
( rc = (*pInputParms->pPSTPutColValue) // 目标列赋值函数 (PST_C_CHAR, // 目标列数据类型 0, //Precision,DECIMAL 数据类型专用,这里不需要 0, //Scale,DECIMAL 数据类型专用,这里不需要 ID, // 转换后的数据 sizeof(ID), // 数据大小 IndVar)); // 赋值是否为空,-1 为空,不空为 0 |
完成了程序的编写,我们需要将每一个 Exit Routine 编译连接生成单独的 DLL 文件,并将该文件放在 Optim 安装目录中 BIN 文件夹下。Optim 会在启动时自动加载该库文件。在本例中,将上面的编写的 Exit Routine 生成 MYEXIT.dll, 并将它放在 Optim 安装目录中 BIN 文件夹下。
然后打开一个新的 Convert 请求,步骤和前面 HASH_LOOKUP 一致。在指定 Column Map 界面,我们在 ID 列所在的位置填写“EXIT MYEXIT”,按 Tab 键,可以发现该行最右侧的 Status 列状态变成 Exit。
选择 Update and return,执行该请求,同样得到成功的报告。
新建一个 Compare 的请求,步骤参考 HASH_LOOKUP 章节中的转换结果部分,得到的比对结果如下:
可以看到,转换同样成功,并且结果和之前利用 HASH_LOOKUP 得到的结果不同,按照我们设计的规则进行了变化。
编写 Column Map Procedure 进行数据转换
除了 Optim 提供的函数和 Exit Routine 之外,在 Windows 平台上,我们还拥有另一个数据转换的工具,这就是 Column Map Procedure。
Column Map Procedure 只能在 Windows 平台上使用,Column Map Procedure 和 Exit routine 的功能一样,不同在于:
Column Map Procedure 的模板如下:
Sub Load ...(Load 函数为可选函数,它在所有 ... 表没有被处理之前调用 ... 可以利用该函数进行初始化工作) ... End Sub Function CmStartTable () As Integer ...( CmStartTable 函数为可选函数, ... 它在每一个表被处理前调用 ... 可以利用该函数对每一个表做 ... 初始化工作) ... End Function Function CmTransform. () As Integer ... ( CmTransform. 函数是必需的, ... 在该函数中定义数据转换的规则) ... End Function Function CmEndTable ... (CmEndTable 只能存在一个, ... 它在每一个表都被处理完成 ... 之后都会被调用) ... End Function Sub Unload() ...( Unload 函数只能存在一个, ... 它在所有表都被处理完成 ... 之后被调用) ... End Sub |
我们需要在 CmTransform. 函数中编写自定义的数据转换规则。
打开 Optim 主界面,选择“Definitions->Column Map Proc...”接下来,我们在打开的 Column Map Proc Editor 中编写程序。
首先,我们要获得源数据列的值,代码如下:
Dim pro As String pro=Source.Column(Target.Column).Value |
然后,我们对源数据进行转换,转换规则与之前的 Exit routine 相同。代码如下:
pos(1)=CInt(30*Rnd(data(15)*100+data(16)*10+data(17))) pos(2)=CInt(30*Rnd(data(15)*100+data(16)*10+data(17))+1)+60 pos(3)=CInt(11*Rnd(data(15)*100+data(16)*10+data(17))+1) ut=Mid(prov,2*pos(1)+1,2) & Mid(pro,3,6) & pos(2) If pos(3) < 10 Then ut=out & "0" & pos(3) Else ut=out & pos(3) End If ut=out & Mid(pro,13,5) data(18)=0 For i=1 To 17 data(18)=data(18) + wi(i)*data(i) Next i data(18)=data(18) Mod 11 ut=out & Mid(yi,data(18)+1,1) |
最后,我们将转换后的数据赋给目标列,代码如下:
Target.Value = out |
完成编写后,将该 procedure 保存并命名。命名规则为 identifier.name。这里命名为 Proc.ID。
下一步,新建一个 Convert 的请求,步骤和前面一样。在 Column Map 界面,在 ID 列对应的位置填入“PROC Proc.ID”并按 Tab 键,该行最右侧的状态将变为“CM Procedure Defined”,如下图所示:
运行该请求,得到成功报告,并进行比较,得到结果如下:
本文通过实例介绍了如何使用 IBM Optim Data Privacy 的基本函数以及高级定制功能对敏感数据进行屏蔽。由于篇幅有限,关于 IBM Optim Data Privacy 中提供的其他定制功能,比如 Age 等没有做实例介绍,有兴趣的读者可以参考 IBM Optim Common Elements Manual 来做进一步了解。这个手册位于 Optim 安装目录下的 DOC 文件夹下。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15082138/viewspace-625475/ ,如需转载,请注明出处,否则将追究法律责任。