我在Oracle 11g中有一个包含NCLOB数据库类型的列。我需要为其内容获取哈希值。如何使用任何内置Oracle函数或在Oracle中的PL / SQL SP内部执行此操作?
答案 0 :(得分: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。根据{{3}}原始可接受的输入类型是RAW,CHAR,VARCHAR2,NCHAR,NVARCHAR2,LONG,BLOB。 RAW /隐式RAW转换,BLOB和CLOB未涵盖的所有其他数据类型(DATE,TIMESTAMP等)必须首先通过TO_CHAR()传递。
值得注意的是dbms_crypto.hash()支持以下散列算法:
密码:以防万一
如果您要存储密码,我建议您使用密码存储哈希(bcrypt,PBKDF2或scrypt)而不是加密哈希(md5,sha-1等)。不同之处在于密码存储哈希意味着需要时间来打破,而密码哈希意味着要快速完成。当通过暴力攻击系统的密码列表时,当试图破坏通过加密算法传递的盐值时,它会花费更多的时间。考虑在单个值上使用密码哈希可能需要大约100毫秒(对于单个真实登录而言并不多),但对于整个密码列表中的暴力(每个密码数百万/数十亿次尝试)来说非常慢。
Oracle仇恨密码哈希
为了它的价值,我不知道Oracle提供密码散列支持的任何软件包。但是,您可以通过使用“implicity data conversions”并将Java bcrypt实现放在使用Oracle RDBMS运行的JVM中来实现此目的。然后,您可以使用loadjava来调用实现bcrypt的Java类。如果您使用的是中间层,则可以使用该语言提供的许多其他选项(.NET,PHP,Perl,Ruby,Python,Java等),并跳过尝试使用'loadjava'。
我的意思是加密而不是哈希!
如果dbms_crypto.hash()不涵盖您需要的哈希,您可能正在通过dbms_crypto.encrypt寻找加密,除非它采用以下类型,否则它的工作方式非常相似:
这是完整的PL/SQL wrapper。所有其他版本均可通过11gR2 documentation on DBMS_CRYPTO获得。只需单击您的版本,然后搜索“dbms_crypto”。