Oracle 11g透明数据加密安全特性解析(下)

日期: 2009-04-13 作者:开心果 来源:TechTarget中国 英文

  DICOM:存储病人医疗影像和元数据的工业标准

  美国放射学会(ACR)和国家电气制造联合会(NEMA)在1993年通过协作将医学影像和通讯(DICOM)标准化了,为医学影像设备和相关应用程序的开发提供了可供参照执行的依据,后来成为存储和传输放射影像通用的标准,Oracle 10g R2完全支持DICOM 3.0标准,但是直到Oracle 11g才实现了对DICOM数据进行加密。

  Oracle 11g扩展了Oracle 10g R2 中ORDImage对象类型的能力,增加了一个新的ORDDicom对象类型,以便更有效地存储DICOM影像,由于ORDDicom对象可以存储在SecureFile LOB中,这样就可以实现压缩、重复数据删除和加密存储在DICOM文件中的影像和相关的元数据的能力,医生、大学和医院使用计算的病人信息,特别是诊断和研究。

  Oracle 10gR2提供了转储病人信息到XML文件的能力,但现在的ORDDicom对象扩展了这些能力,使得可以直接在Oracle 11g数据库查询病人的元数据,这就意味着可以使用新的高级索引特性如XMLIndex数据类型来检索特殊的病人信息,此外,Oracle 11g现在还可以创建、存储、展现和检索存储在ORDDicom对象内的数据影像的指纹特征,也就是说将会更容易选中正确的病人信息,ORDDicom数据模型也可以帮助保证病人信息的机密性,因为它提供了一个方法可以避免泄露来自DICOM文件病人元数据中的私密信息。

  1、创建DICOM对象

  为了说明如何使用这些强大的功能特性增强Oracle 11g SecureFile的加密能力,我创建了一个新的方案和表MIPS.PATIENT_IMAGES,我将使用这个表存储DICOM元数据,并在ORDDicom和ORDImage数据类型列中存储影像数据,DICOM_IMAGE列将会存储来自对应的源文件直接载入的DICOM信息,ANONYMOUS列将会存储病人的敏感数据,THUMBPRINT列将会存储来自每个DICOM文件中第一个影像的指纹图像,清单4显示了我创建这个表的DDL语句。

  清单4 创建加密的SecureFile LOB存储敏感信息 

创建一个用户(MIPS)
  DROP USER mips CASCADE;
  CREATE USER mips
  IDENTIFIED BY mips
  DEFAULT TABLESPACE patimages
  TEMPORARY TABLESPACE temp
  QUOTA UNLIMITED ON patimages;
  GRANT CONNECT, RESOURCE TO mips;
  GRANT EXECUTE ANY PROCEDURE to mips;
  GRANT CREATE ANY DIRECTORY TO mips;

  创建一个新的目录  

DROP DIRECTORY mips_imgs;
  CREATE OR REPLACE DIRECTORY mips_imgs
  AS ‘/home/oracle/dicom’;
  GRANT READ ON DIRECTORY mips_imgs TO mips;

  创建一个新表MIPS.PATIENT_IMAGES使用SecureFile LOB存储DICOM文件。


DROP TABLE mips.patient_images PURGE;
  CREATE TABLE mips.patient_images (
  patient_id NUMBER
  ,name VARCHAR2(30)
  ,ssn VARCHAR2(11)
  ,dob DATE
  ,dicom_image ORDSYS.ORDDICOM
  ,anonymous ORDSYS.ORDDICOM
  ,thumbprint ORDSYS.ORDIMAGE
  )
  TABLESPACE patimages
  LOB(dicom_image.source.localData)
  STORE AS SECUREFILE (
  TABLESPACE patimages
  DISABLE STORAGE IN ROW
  DEDUPLICATE
  COMPRESS HIGH
  CACHE READS
  )
  LOB(anonymous.source.localData)
  STORE AS SECUREFILE (
  TABLESPACE patimages
  DISABLE STORAGE IN ROW
  DEDUPLICATE
  COMPRESS HIGH
  CACHE READS
  )
  LOB(thumbprint.source.localData)
  STORE AS SECUREFILE (
  TABLESPACE patimages
  DISABLE STORAGE IN ROW
  DEDUPLICATE
  COMPRESS HIGH
  CACHE READS
  )
  ;
  – 注释
  COMMENT ON TABLE mips.patient_images
  IS ‘Contains Patient metadata and DICOM images’;
  COMMENT ON COLUMN mips.patient_images.patient_id
  IS ‘Unique identifier for a Patient’;
  COMMENT ON COLUMN mips.patient_images.name
  IS ‘Patient Name’;
  COMMENT ON COLUMN mips.patient_images.ssn
  IS ‘Patient Social Security Number’;
  COMMENT ON COLUMN mips.patient_images.dob
  IS ‘Patient Date of Birth’;
  COMMENT ON COLUMN mips.patient_images.dicom_image
  IS ‘DICOM LOB’;
  COMMENT ON COLUMN mips.patient_images.anonymous
  IS ‘Anonymous DICOM LOB’;
  COMMENT ON COLUMN mips.patient_images.thumbprint
  IS ‘Thumbprint of DICOM image’;
  – 创建索引和约束
  CREATE UNIQUE INDEX mips.patient_images_pk_idx
  ON mips.patient_images(patient_id)
  TABLESPACE patimages;
  ALTER TABLE mips.patient_images
  ADD CONSTRAINT patient_images_pk
  PRIMARY KEY (patient_id);

  2、从DICOM源文件转移到ORDDicom对象

  现在我已经为DICOM信息创建好了适当的资料库,我将要使用SQL*Loader直接从DICOM源文件中提取并格式化病人元数据,对于我的源数据,我将使用若干个简单的DICOM文件,这些DICOM文件都是从http://www.barre.nom.fr/medical/下载得到的,病人的姓名和其它信息完全是虚构的,只是为了说明这些概念,清单5显示了SQL*Loader用于初始化、格式化和从这些源文件中载入DICOM数据到ORDDicom和ORDImage数据类型列的参数文件,以及调用SQL*Loader执行这个初始化数据载入的结果。

  清单5 使用SQL*Loader载入DICOM原始文件到Oracle 11g数据库中

 – SQL*Loader参数文件: LoadDICOMFromFile.sqlparms

  – 目的: 这个参数文件将直接从DICOM文件载入DICOM数据到MIPS.PATIENT_IMAGES 表的DICOM_IMAGE 列,它也控制了ANONYMOUS列(它容纳匿名的DICOM数据)和THUMBPRINT列(它容纳DICOM图像本身的指纹图像)的初始化。


LOAD DATA
  INFILE *
  INTO TABLE mips.patient_images
  TRUNCATE
  FIELDS TERMINATED BY WHITESPACE
  OPTIONALLY ENCLOSED BY ‘”‘
  (
  patient_id INTEGER EXTERNAL
  ,name CHAR
  ,ssn CHAR
  ,dob DATE “yyyy-mm-dd”
  ,fn FILLER CHAR
  – 载入列对象MIPS.PATIENT_IMAGES.DICOM_IMAGE:
  – 1.) LOB属性source.localData和DICOM数据一起载入。
  – 2.) 属性srcType被设置为”local”。
  – 3.) 属性updateTime被初始化到当前日期。
  – 4.) LOB属性扩展使用空的LOB进行初始化。
  ,dicom_image COLUMN OBJECT (
  source COLUMN OBJECT (
  localData LOBFILE(fn) TERMINATED BY EOF
  ,srcType CONSTANT ‘local’
  ,updateTime EXPRESSION “SYSDATE”
  )
  ,extension LOBFILE(fn) TERMINATED BY EOF
  DEFAULTIF dicom_image.source.srcType=’local’
  )
  – 初始化(但不载入)列对象MIPS.PATIENT_IMAGES.ANONYMOUS:
  – 1.) LOB属性source.localData和扩展被初始化。
  – 2.) srcType属性被初始化为”local”。
  – 3.) localData LOB将容纳DICOM数据的匿名内容。
  – 4.) srcType属性被初始化为”local”。
  – 5.) LOB扩展是一个由ORDDICOM使用的内部字段。
  ,anonymous COLUMN OBJECT (
  source COLUMN OBJECT (
  localData LOBFILE(fn) TERMINATED BY EOF
  DEFAULTIF anonymous.source.srcType=’local’
  ,srcType CONSTANT ‘LOCAL’
  )
  ,extension LOBFILE(fn) TERMINATED BY EOF
  DEFAULTIF dicom_image.source.srcType=’local’
  )
  – 初始化(但不载入)列对象MIPS.PATIENT_IMAGES.THUMBPRINT:
  – 1.) LOB属性扩展被一个空的LOB初始化。
  – 2.) LOB属性source.localData被一个空的LOB初始化。
  – 3.) 本地属性被初始化为1。
  ,thumbprint COLUMN OBJECT (
  source COLUMN OBJECT (
  localData LOBFILE(fn) TERMINATED BY EOF
  DEFAULTIF thumbprint.source.local=X’1′
  ,local CONSTANT 1
  )
  )
  )
  BEGINDATA
  101 “Ames, Aldritch” 322-51-1111 1907-12-01 CT-MONO2-16-ankle.dcm
  202 “Barry, Dave” 345-21-2222 1968-12-24 OT-MONO2-8-colon.dcm
  303 “Colson, Charles” 342-43-3333 1931-11-03 MR-MONO2-8-16x-heart.dcm
  404 “Dean, John” 322-09-4444 1942-02-18 NM-MONO2-16-13x-heart.dcm
  505 “Ehrlichman, John” 345-09-5555 1914-08-01 US-PAL-8-10x-echo.dcm
  606 “Haldeman, Robert” 322-18-6666 1918-11-11 US-RGB-8-esopecho.dcm
  >>> SQL*Loader results:
  SQL*Loader: Release 11.1.0.6.0 – Production on Sat Mar 14 13:00:40 2009
  Copyright (c) 1982, 2007, Oracle. All rights reserved.
  Control File: LoadDICOMFromFile.sqlparms
  Data File: LoadDICOMFromFile.sqlparms
  Bad File: LoadDICOMFromFile.bad
  Discard File: none specified
  (Allow all discards)
  Number to load: ALL
  Number to skip: 0
  Errors allowed: 50
  Bind array: 64 rows, maximum of 256000 bytes
  Continuation: none specified
  Path used: Conventional
  Table MIPS.PATIENT_IMAGES, loaded from every logical record.
  Insert option in effect for this table: TRUNCATE
  Column Name Position Len Term Encl Datatype
  —————————— ———- —– —- —- ———————
  PATIENT_ID FIRST * WHT O(“) CHARACTER
  NAME NEXT * WHT O(“) CHARACTER
  SSN NEXT * WHT O(“) CHARACTER
  DOB NEXT * WHT O(“) DATE yyyy-mm-dd
  FN NEXT * WHT O(“) CHARACTER
  (FILLER FIELD)
  DICOM_IMAGE DERIVED * COLUMN OBJECT
  *** Fields in DICOM_IMAGE
  SOURCE DERIVED * COLUMN OBJECT
  *** Fields in DICOM_IMAGE.SOURCE
  LOCALDATA DERIVED * EOF CHARACTER
  Dynamic LOBFILE. Filename in field FN
  SRCTYPE CONSTANT
  Value is ‘local’
  UPDATETIME EXPRESSION
  SQL string for column : “SYSDATE”
  *** End of fields in DICOM_IMAGE.SOURCE
  EXTENSION DERIVED * EOF CHARACTER
  Dynamic LOBFILE. Filename in field FN
  DEFAULT if DICOM_IMAGE.SOURCE.SRCTYPE = 0X6c6f63616c(character ‘local’)
  *** End of fields in DICOM_IMAGE
  ANONYMOUS DERIVED * COLUMN OBJECT
  *** Fields in ANONYMOUS
  SOURCE DERIVED * COLUMN OBJECT
  *** Fields in ANONYMOUS.SOURCE
  LOCALDATA DERIVED * EOF CHARACTER
  Dynamic LOBFILE. Filename in field FN
  DEFAULT if ANONYMOUS.SOURCE.SRCTYPE = 0X6c6f63616c(character ‘local’)
  SRCTYPE CONSTANT
  Value is ‘LOCAL’
  *** End of fields in ANONYMOUS.SOURCE
  EXTENSION DERIVED * EOF CHARACTER
  Dynamic LOBFILE. Filename in field FN
  DEFAULT if DICOM_IMAGE.SOURCE.SRCTYPE = 0X6c6f63616c(character ‘local’)
  *** End of fields in ANONYMOUS
  THUMBPRINT DERIVED * COLUMN OBJECT
  *** Fields in THUMBPRINT
  SOURCE DERIVED * COLUMN OBJECT
  *** Fields in THUMBPRINT.SOURCE
  LOCALDATA DERIVED * EOF CHARACTER
  Dynamic LOBFILE. Filename in field FN
  DEFAULT if THUMBPRINT.SOURCE.LOCAL = 0X01(character ”)
  LOCAL CONSTANT
  Value is ‘1’
  *** End of fields in THUMBPRINT.SOURCE
  *** End of fields in THUMBPRINT
  Table MIPS.PATIENT_IMAGES:
  6 Rows successfully loaded.
  0 Rows not loaded due to data errors.
  0 Rows not loaded because all WHEN clauses were failed.
  0 Rows not loaded because all fields were null.
  Space allocated for bind array: 83456 bytes(64 rows)
  Read buffer bytes: 1048576
  Total logical records skipped: 0
  Total logical records read: 6
  Total logical records rejected: 0
  Total logical records discarded: 0
  Run began on Sat Mar 14 13:00:40 2009
  Run ended on Sat Mar 14 13:00:49 2009
  Elapsed time was: 00:00:09.65
  CPU time was: 00:00:00.61

  3、生成指纹图像和匿名的元数据

  为了完成ANONYMOUS和THUMBPRINT列的填充,我将使用一些技巧:

  (1)首先,我将通过调用setModel 方法载入ORDDicom对象模型,这个对象模型必须在调用其它方法之前载入。

  (2)然后使用processCopy方法生成一张150×200的JPEG图像,将其存储到THUMBPRINT列中。

  (3)最后,我使用makeAnonymous方法创建一个匿名版本的DICOM_IMAGE列数据,并将其存储到ANONYMOUS列中。

  清单6 显示了如何在最初被载入MIPS.PATIENT_IMAGES表中的所有行上执行这些方法。

  清单6 从前面载入的ORDDicom对象创建和存储匿名的病人信息和指纹图像:

  1)将DICOM模型载入到内存中。

  2)将原始的DICOM文件元数据转换成对应的元素。

  3)基于原始的DICOM影像以JPEG格式创建一个缩略图。

  4)生成一个匿名的DICOM文件版本。

  5)将新的信息保存到它们对应的SecureFile LOB中。

SET SERVEROUTPUT ON
  DECLARE
  dcm_row ORDSYS.ORDDICOM;
  BEGIN
  – 载入DICOM数据模型
  ord_dicom.setDatamodel;
  – 在医学图像表中遍历所有行
  FOR dcm_row IN (
  SELECT
  patient_id
  ,dicom_image
  ,anonymous
  ,thumbprint
  FROM mips.patient_images
  FOR UPDATE
  )
  LOOP
  BEGIN
  —–
  –通过setProperties存储过程初始化DICOM SecureFile LOB列属性
  —–
  dcm_row.dicom_image.setProperties();
  —–
  – 在原始DICOM影像的基础上构建一个缩略图图像
  —–
  dcm_row.dicom_image.processCopy(‘fileFormat=JPEG fixedScale=150,200’, dcm_row.thumbprint);
  —–
  – 通过makeAnonymous()函数生成DICOM对象的匿名版本
  —–
  dcm_row.dicom_image.makeAnonymous(genUID(dcm_row.patient_id), dcm_row.anonymous);
  —–
  – 将新产生的信息保存到它们对应的SecureFile LOB中
  —–
  UPDATE mips.patient_images
  SET dicom_image = dcm_row.dicom_image
  ,anonymous = dcm_row.anonymous
  ,thumbprint = dcm_row.thumbprint
  WHERE patient_id = dcm_row.patient_id;
  EXCEPTION
  WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE(‘Error processing image for Patient ID #’ || dcm_row.patient_id);
  END;
  END LOOP;
  COMMIT;
  END;
  /

  4、使用ORDDicom和ORDImage列的内容

  最后,我已经准备好研究这些已经载入到DICOM列的DICOM信息,幸运的是,ORDDicom数据类型使得这些工作变得相当简单,因为它提供了多种方法来直接查询病人的元数据属性,清单7显示了一个简单的查询,它直接从DICOM_IMAGE和THUMBPRINT列查询多个属性。

  清单7 查看已经载入到ORDDICOM和ORDIMAGE对象中的元数据

  显示选择的内容:

  1)普通数据类型

  2)ORDDICOM数据类型

  3)ORDIMAGE数据类型 


SET LINESIZE 80
  SET PAGESIZE 80
  TTITLE ‘Sample Patient Metadata|(from MIPS.PATIENT_IMAGES)’
  COLUMN patient_id FORMAT 99999 HEADING ‘Pat|ID’
  COLUMN name FORMAT A20 HEADING ‘Patient Name’ WRAP
  COLUMN ssn FORMAT A11 HEADING ‘Patient SSN’
  COLUMN di_sop_uid FORMAT A30 HEADING ‘DICOM Image SOP UID’ WRAP
  COLUMN tp_len FORMAT 99999 HEADING ‘Thumb|Print|Image|Size’
  SELECT
  PI.patient_id
  ,PI.name
  ,PI.ssn
  ,PI.dicom_image.sop_instance_uid AS di_sop_uid
  ,PI.thumbprint.getcontentlength() AS tp_len
  FROM mips.patient_images PI
  ORDER BY PI.patient_id
  ;
  TTITLE OFF
  Sun Mar 15 page 1
  Sample Patient Metadata
  (from MIPS.PATIENT_IMAGES)
  Thumb
  Print
  Pat Image
  ID Patient Name Patient SSN DICOM Image SOP UID Size
  —— ——————– ———– —————————— ——
  101 Ames, Aldritch 322-51-1111 1.2.840.113619.2.1.2411.103115 5034
  2382.365.1.736169244
  202 Barry, Dave 345-21-2222 1.3.46.670589.17.1.7.0.16 5677
  303 Colson, Charles 342-43-3333 999.999.2.19960619.163000.1.10 3648
  3
  404 Dean, John 322-09-4444 2.16.840.1.113662.5.8796818449 1596
  476.121423489.1.1.3101.5309511
  143
  505 Ehrlichman, John 345-09-5555 999.999.133.1996.1.1800.1.6.25 5252
  606 Haldeman, Robert 322-18-6666 999.999.2.19941105.112000.2.10 4683
  7

  校验存储在ORDDicom或ORDImage数据类型列中的图像需要一点技巧,因为需要一个接口才能查看这些图像,因为这些图像都采用基于工业标准的格式存储,如JPEG,TIF,PNG等,所以有大量的免费图像查看程序可以拿来使用。

  小结

  Oracle 11g新的SecureFile特性大大扩展在Oracle数据库中存储大对象的能力,并提高了安全性和有效性,SecureFILE LOB的压缩和重复数据删除功能在空间利用上更是让人惊讶,SecureFILE LOB的透明数据加密特性让存储在Oracle 11g数据库中的敏感信息和机密信息安全性更有保障,这些特性让Oracle 11g数据库成为美国新的联邦政府在启动存储医院、病人和医疗元数据方面的主要候选数据库。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐