15

可能重复:
PL/SQL 中有散列函数吗?

我在 Oracle 11g 中有一个 NCLOB 数据库类型的列。我需要为其内容获取哈希值。如何使用任何内置的 Oracle 函数或在 Oracle 的 PL/SQL SP 中执行此操作?

4

1 回答 1

38

是的:散列和加密(相关但不完全相同)都是通过 SYS 包 DBMS_CRYPTO 完成的。

简单的 SHA-1 散列

l_hash := dbms_crypto.hash( l_src, dbms_crypto.HASH_SH1 );

简单的 MD5 散列

l_hash := dbms_crypto.hash( l_src, dbms_crypto.HASH_MD5 );

dbms_crypto.hash() 概述

hash() 函数被重载以接受以下类型:RAW、BLOB 和 CLOB。根据原始可接受输入类型的隐式数据转换为 RAW、CHAR、VARCHAR2、NCHAR、NVARCHAR2、LONG、BLOB。RAW/隐式 RAW 转换、BLOB 和 CLOB 未涵盖的所有其他数据类型(DATE、TIMESTAMP 等)必须首先通过 TO_CHAR()。

值得注意的是 dbms_crypto.hash() 支持以下散列算法:

  • HASH_MD4
  • HASH_MD5
  • HASH_SH1

密码:以防万一

如果您要存储密码,我建议您使用密码存储散列(bcrypt、PBKDF2 或 scrypt)而不是加密散列(md5、sha-1 等)。不同之处在于密码存储哈希意味着需要时间来破解,而加密哈希意味着快速完成。当通过蛮力攻击系统的密码列表时,在尝试破解通过密码算法传递的加盐值时,它的时间密集度要高出几个数量级。考虑到在单个值上使用密码哈希可能需要大约 100 毫秒(对于单个真实登录来说并不多),但对于整个密码列表的蛮力(每个密码尝试数百万/十亿次)来说非常慢。

Oracle 讨厌密码哈希

对于它的价值,我不知道 Oracle 提供的任何提供密码散列支持的软件包。但是,您可以通过使用“ loadjava ”并将 Java bcrypt 实现放入与 Oracle 的 RDBMS 一起运行的 JVM 中来完成此操作。然后,您可以使用PL/SQL 包装器来调用实现 bcrypt 的 Java 类。如果您使用的是中间层,则可以使用该语言(.NET、PHP、Perl、Ruby、Python、Java 等)提供的许多其他选项,而无需尝试使用“loadjava”。

我的意思是加密不是哈希!

如果您需要的散列没有被 dbms_crypto.hash() 覆盖,您可能正在寻找通过 dbms_crypto.encrypt 进行的加密,它的工作原理非常相似,只是它采用以下类型:

  • ENCRYPT_DES
  • ENCRYPT_3DES_2KEY
  • ENCRYPT_3DES
  • 加密_AES
  • ENCRYPT_PBE_MD5DES
  • 加密_AES128
  • 加密_AES192
  • 加密_AES256

这是关于 DBMS_CRYPTO的完整11gR2 文档。所有其他版本均可通过tahiti.oracle.com获得。只需单击您的版本,然后搜索“dbms_crypto”。

于 2012-06-18T16:36:03.447 回答