1

如何识别 oracle 中的列是否使用 DBMS_CRYPTO.HASH 或 DBMS_OBFUSCATION_TOOLKIT.MD5 加密

具有 HASH 值的表

是否有任何函数可以跨 oracle 数据库(ALL_TAB_COLUMNS)的所有列运行,如果列是否加密,它将返回 true?

4

1 回答 1

1

我认为很难识别加密的列。但是,应该很容易找到候选列,因为它们通常只包含十六进制数据并且是固定长度的。

在 Oracle 中存储十六进制数据有两种常见的方式,作为一个RAW或作为一个字符串(CHARVARCHAR2)。RAW是原始数据的正确数据类型,因为您没有字符集问题,并且字符大小写是明确的(f6099c0 与 F6099C0 相同),并且大小只有一半。然而,根据我的经验,不幸的是,字符串的使用频率更高,主要是因为开发人员从未听说过RAW数据类型。不过,在寻找哈希值时,您必须同时寻找两者。

一些示例数据:

CREATE TABLE t (
   md5r  RAW(16), 
   md5v  CHAR(32),
   sha1r RAW(20),
   sha1v CHAR(40)
);

INSERT INTO t
SELECT md5raw, rawtohex(md5raw) as md5str,
       sh1raw, rawtohex(sh1raw) as sh1str
  FROM (SELECT DBMS_CRYPTO.Hash(tr, 2) AS md5raw,
               DBMS_CRYPTO.Hash(tr, 3) AS sh1raw
          FROM (SELECT UTL_I18N.STRING_TO_RAW (tv, 'AL32UTF8') AS tr
                  FROM (SELECT object_name as tv FROM dba_objects where rownum <= 10)));
EXEC dbms_stats.gather_table_stats(null, 't');

您现在可以通过列中的最高值与最低值一样长的事实来过滤出候选列。由于低/高值存储为十六进制字符串,因此对于 MD5,您需要将长度(相当混乱)加倍为 32/64,对于 SHA1 等为 40/80:

SELECT owner, table_name, column_name, data_type, data_length
  FROM all_tab_columns 
 WHERE data_type = 'RAW' 
   AND LENGTH(low_value)=40 AND LENGTH(high_value)=40;

T SHA1R RAW 20

SELECT owner, table_name, column_name, data_type, data_length
  FROM all_tab_columns 
 WHERE data_type IN ('CHAR','VARCHAR','VARCHAR2')
   AND LENGTH(low_value)=80 AND LENGTH(high_value)=80;

T SHA1V CHAR 40

接下来,我将检查表中的所有值对于这些候选人来说是否都是固定长度。如果桌子很大,我会从一个小样本开始。例如对于列 sha1r:

SELECT min(length(sha1r)) as min_len, 
       max(length(sha1r)) as max_len, 
       count(*) as n 
  FROM t SAMPLE (0.1);

接下来,我会检查字符串版本是否都是十六进制字符(原始版本显然不需要):

SELECT sha1v, CASE WHEN (REGEXP_LIKE(sha1v,'^[0-9A-Fa-f]*$')) THEN 1 ELSE 0 END as hex
  FROM t;

现在您可以使用问题中提到的https://code.google.com/archive/p/hash-identifier/之类的工具来检查哈希类型。

您的示例F6099C0932D0E2B13286219F99C265975B33FD84导致

Possible Hashs:
[+]  SHA-1
[+]  MySQL5 - SHA-1(SHA-1($pass))

顺便说一句,请使用文本而不是图像,我不得不手动输入您的示例来尝试,而不是复制和粘贴,这很痛苦。

于 2020-05-11T11:22:07.537 回答