内容

名称

Digest::SHA - Perl 扩展用于 SHA-1/224/256/384/512

概要

在程序中

	# Functional interface

use Digest::SHA qw(sha1 sha1_hex sha1_base64 ...);

$digest = sha1($data);
$digest = sha1_hex($data);
$digest = sha1_base64($data);

$digest = sha256($data);
$digest = sha384_hex($data);
$digest = sha512_base64($data);

	# Object-oriented

use Digest::SHA;

$sha = Digest::SHA->new($alg);

$sha->add($data);		# feed data into stream

$sha->addfile(*F);
$sha->addfile($filename);

$sha->add_bits($bits);
$sha->add_bits($data, $nbits);

$sha_copy = $sha->clone;	# make copy of digest object
$state = $sha->getstate;	# save current state to string
$sha->putstate($state);		# restore previous $state

$digest = $sha->digest;		# compute digest
$digest = $sha->hexdigest;
$digest = $sha->b64digest;

从命令行

$ shasum files

$ shasum --help

概要 (HMAC-SHA)

	# Functional interface only

use Digest::SHA qw(hmac_sha1 hmac_sha1_hex ...);

$digest = hmac_sha1($data, $key);
$digest = hmac_sha224_hex($data, $key);
$digest = hmac_sha256_base64($data, $key);

摘要

Digest::SHA 是 NIST 安全散列标准的完整实现。它为 Perl 程序员提供了一种方便的方法来计算 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224 和 SHA-512/256 消息摘要。该模块可以处理所有类型的输入,包括部分字节数据。

描述

Digest::SHA 是用 C 语言编写的,速度很快。如果您的平台缺少 C 编译器,您可以安装功能等效(但速度慢得多)的 Digest::SHA::PurePerl 模块。

编程接口易于使用:它与 CPAN 的 Digest 模块中找到的接口相同。因此,如果您的应用程序当前使用 Digest::MD5 并且您更喜欢 SHA 的更强安全性,则可以轻松地将它们转换。

该接口提供两种计算摘要的方法:一次性计算或分阶段计算。为了说明,以下简短程序使用每种方法计算“hello world”的 SHA-256 摘要

use Digest::SHA qw(sha256_hex);

$data = "hello world";
@frags = split(//, $data);

# all-at-once (Functional style)
$digest1 = sha256_hex($data);

# in-stages (OOP style)
$state = Digest::SHA->new(256);
for (@frags) { $state->add($_) }
$digest2 = $state->hexdigest;

print $digest1 eq $digest2 ?
	"whew!\n" : "oops!\n";

要计算一个 n 位消息的摘要,其中 n 不是 8 的倍数,请使用 add_bits() 方法。例如,考虑由 148 次重复的位串“110”加上“11”组成的 446 位消息。以下是显示其 SHA-1 摘要的方法

use Digest::SHA;
$bits = "110" x 148 . "11";
$sha = Digest::SHA->new(1)->add_bits($bits);
print $sha->hexdigest, "\n";

请注意,对于较大的位串,使用带两个参数的版本 add_bits($data, $nbits) 更有效,其中 $data 采用 Perl 字符串使用的常规打包二进制格式。

该模块还允许您将中间 SHA 状态保存到字符串中。getstate() 方法生成可移植的、人类可读的文本,描述计算的当前状态。您可以随后使用 putstate() 恢复该状态,以从计算停止的地方继续。

要查看状态描述的外观,只需运行以下代码

use Digest::SHA;
print Digest::SHA->new->add("Shaw" x 1962)->getstate;

为了方便起见,Digest::SHA 模块提供了使用 HMAC-SHA-1/224/256/384/512 算法计算带密钥哈希的例程。这些服务仅以函数形式存在,并模仿 sha()sha_hex()sha_base64() 函数的样式和行为。

# Test vector from draft-ietf-ipsec-ciph-sha-256-01.txt

use Digest::SHA qw(hmac_sha256_hex);
print hmac_sha256_hex("Hi There", chr(0x0b) x 32), "\n";

UNICODE 和副作用

从版本 5.6 开始,Perl 支持 Unicode 字符串。此类字符串可能包含宽字符,即其序数值大于 255 的字符。这可能会给 SHA 等摘要算法带来问题,这些算法被指定为对字节序列进行操作。

Digest::SHA 处理 Unicode 字符串的规则很容易说明,但可能难以理解:该字符串被解释为字节值的序列,其中每个字节值等于其对应 Unicode 字符的序数值(即代码点)。这样,Unicode 字符串 'abc' 与普通字符串 'abc' 具有完全相同的摘要值。

由于宽字符不适合一个字节,因此如果 Digest::SHA 例程遇到宽字符,它们会报错。而如果 Unicode 字符串不包含宽字符,则该模块会很乐意接受它。以下代码说明了这两种情况

$str1 = pack('U*', (0..255));
print sha1_hex($str1);		# ok

$str2 = pack('U*', (0..256));
print sha1_hex($str2);		# croaks

请注意,摘要例程会将 UTF-8 输入静默转换为其在本地编码中的等效字节序列(参见 utf8::downgrade)。此副作用仅影响 Perl 在内部存储数据的方式,但不会影响数据的实际值。

NIST 关于 SHA-1 的声明

NIST 承认王小云教授的工作构成了对 SHA-1 的实际碰撞攻击。因此,NIST 鼓励快速采用 SHA-2 哈希函数(例如 SHA-256)用于需要强碰撞抵抗的应用程序,例如数字签名。

参考:http://csrc.nist.gov/groups/ST/hash/statement.html

Base64 摘要的填充

按照惯例,CPAN Digest 模块不会填充其 Base64 输出。当将此类摘要提供给期望正确填充的 Base64 编码的其他软件时,可能会出现问题。

目前,任何必要的填充都必须由用户完成。幸运的是,这是一个简单的操作:如果 Base64 编码的摘要的长度不是 4 的倍数,只需在摘要末尾追加“=”字符,直到它是 4 的倍数。

while (length($b64_digest) % 4) {
	$b64_digest .= '=';
}

举例来说,sha256_base64("abc") 计算结果为

ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0

其长度为 43。因此,正确填充的版本为

ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=

导出

默认情况下没有导出。

可导出函数

如果您的 C 编译器支持 64 位类型(例如 C99 的long long,或 Microsoft C/C++ 使用的__int64),所有这些函数都将可用。否则,您将无法执行 SHA-384 和 SHA-512 变换,这两者都需要 64 位操作。

函数式风格

sha1($data, ...)
sha224($data, ...)
sha256($data, ...)
sha384($data, ...)
sha512($data, ...)
sha512224($data, ...)
sha512256($data, ...)

将参数逻辑地连接成单个字符串,并返回其 SHA-1/224/256/384/512 摘要,以二进制字符串形式编码。

sha1_hex($data, ...)
sha224_hex($data, ...)
sha256_hex($data, ...)
sha384_hex($data, ...)
sha512_hex($data, ...)
sha512224_hex($data, ...)
sha512256_hex($data, ...)

将参数逻辑地连接成单个字符串,并返回其 SHA-1/224/256/384/512 摘要,以十六进制字符串形式编码。

sha1_base64($data, ...)
sha224_base64($data, ...)
sha256_base64($data, ...)
sha384_base64($data, ...)
sha512_base64($data, ...)
sha512224_base64($data, ...)
sha512256_base64($data, ...)

将参数逻辑地连接成单个字符串,并返回其 SHA-1/224/256/384/512 摘要,以 Base64 字符串形式编码。

需要注意的是,生成的字符串**不**包含 Base64 编码中典型的填充字符。这种省略是故意的,是为了与 CPAN Digest 模块系列保持兼容性。有关详细信息,请参阅"PADDING OF BASE64 DIGESTS"

OOP 风格

new($alg)

返回一个新的 Digest::SHA 对象。$alg 的允许值为 1、224、256、384、512、512224 或 512256。也可以使用算法的常见字符串表示形式(例如“sha256”、“SHA-384”)。如果参数缺失,默认使用 SHA-1。

new 作为实例方法调用将重置对象到与$alg 关联的初始状态。如果参数缺失,对象将继续使用创建时选择的相同算法。

reset($alg)

此方法与new($alg)具有完全相同的效果。实际上,reset只是new的别名。

hashsize

返回此对象的摘要位数。对于 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224 和 SHA-512/256,这些值分别为 160、224、256、384、512、224 和 256。

algorithm

返回此对象的摘要算法。对于 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224 和 SHA-512/256,这些值分别为 1、224、256、384、512、512224 和 512256。

clone

返回对象的副本。

add($data, ...)

将参数逻辑地连接成单个字符串,并使用它来更新当前摘要状态。换句话说,以下语句具有相同的效果

$sha->add("a"); $sha->add("b"); $sha->add("c");
$sha->add("a")->add("b")->add("c");
$sha->add("a", "b", "c");
$sha->add("abc");

返回值是更新后的对象本身。

add_bits($data, $nbits)
add_bits($bits)

通过将位追加到当前摘要状态来更新它。返回值是更新后的对象本身。

第一种形式会导致$data的最高$nbits位追加到流中。$data参数采用 Perl 字符串使用的常规二进制格式。

第二种形式以包含“0”和“1”字符的 ASCII 字符串作为其参数。它等效于

$sha->add_bits(pack("B*", $bits), length($bits));

因此,以下两个语句执行相同的操作

$sha->add_bits("111100001010");
$sha->add_bits("\xF0\xA0", 12);

请注意,SHA-1 和 SHA-2 对其内部状态使用最高有效位排序。这意味着

$sha3->add_bits("110");

等效于

$sha3->add_bits("1")->add_bits("1")->add_bits("0");
addfile(*FILE)

FILE读取直到 EOF,并将该数据追加到当前状态。返回值是更新后的对象本身。

addfile($filename [, $mode])

读取$filename的内容,并将该数据追加到当前状态。返回值是更新后的对象本身。

默认情况下,$filename只是打开并读取;不使用任何特殊模式或 I/O 规则。要更改此设置,请将可选的$mode参数设置为以下值之一

"b"	read file in binary mode

"U"	use universal newlines

"0"	use BITS mode

“U”模式模拟 Python 的“通用换行符”概念,其中 DOS 和 Mac OS 行终止符在处理之前在内部转换为 UNIX 换行符。这确保在跨多个文件系统同时工作时获得一致的摘要值。“U”模式仅影响文本文件,即通过 Perl 的-T测试的文件;二进制文件在没有任何转换的情况下进行处理。

BITS 模式 ("0") 将$filename的内容解释为一个逻辑位流,其中每个 ASCII '0' 或 '1' 字符分别代表一个 0 或 1 位。所有其他字符将被忽略。这提供了一种便捷的方式,通过使用文件来计算部分字节数据的摘要值,而不是必须编写使用add_bits方法的单独程序。

getstate

返回一个字符串,其中包含当前 SHA 状态的可移植、人类可读的表示形式。

putstate($str)

返回一个 Digest::SHA 对象,该对象表示$str中包含的 SHA 状态。$str的格式与方法getstate产生的输出格式匹配。如果作为类方法调用,则会创建一个新对象;如果作为实例方法调用,则对象将重置为$str中包含的状态。

dump($filename)

getstate的输出写入$filename。如果参数缺失或等于空字符串,则状态信息将写入 STDOUT。

load($filename)

返回一个 Digest::SHA 对象,该对象是在$filename的内容上调用putstate的结果。如果参数缺失或等于空字符串,则状态信息将从 STDIN 读取。

digest

返回以二进制字符串编码的摘要。

请注意,digest方法是只读操作。一旦执行,Digest::SHA 对象将自动重置,以准备计算另一个摘要值。如果需要保留原始摘要状态,请调用$sha->clone->digest

hexdigest

返回以十六进制字符串编码的摘要。

digest类似,此方法是只读操作。如果需要保留原始摘要状态,请调用$sha->clone->hexdigest

b64digest

返回以 Base64 字符串编码的摘要。

digest类似,此方法是只读操作。如果需要保留原始摘要状态,请调用$sha->clone->b64digest

需要注意的是,生成的字符串**不**包含 Base64 编码中典型的填充字符。这种省略是故意的,是为了与 CPAN Digest 模块系列保持兼容性。有关详细信息,请参阅"PADDING OF BASE64 DIGESTS"

HMAC-SHA-1/224/256/384/512

hmac_sha1($data, $key)
hmac_sha224($data, $key)
hmac_sha256($data, $key)
hmac_sha384($data, $key)
hmac_sha512($data, $key)
hmac_sha512224($data, $key)
hmac_sha512256($data, $key)

返回$data/$key的HMAC-SHA-1/224/256/384/512摘要,结果以二进制字符串编码。允许使用多个$data参数,前提是$key是列表中的最后一个参数。

hmac_sha1_hex($data, $key)
hmac_sha224_hex($data, $key)
hmac_sha256_hex($data, $key)
hmac_sha384_hex($data, $key)
hmac_sha512_hex($data, $key)
hmac_sha512224_hex($data, $key)
hmac_sha512256_hex($data, $key)

返回$data/$key的HMAC-SHA-1/224/256/384/512摘要,结果以十六进制字符串编码。允许使用多个$data参数,前提是$key是列表中的最后一个参数。

hmac_sha1_base64($data, $key)
hmac_sha224_base64($data, $key)
hmac_sha256_base64($data, $key)
hmac_sha384_base64($data, $key)
hmac_sha512_base64($data, $key)
hmac_sha512224_base64($data, $key)
hmac_sha512256_base64($data, $key)

返回$data/$key的HMAC-SHA-1/224/256/384/512摘要,结果以Base64字符串编码。允许使用多个$data参数,前提是$key是列表中的最后一个参数。

需要注意的是,生成的字符串**不**包含 Base64 编码中典型的填充字符。这种省略是故意的,是为了与 CPAN Digest 模块系列保持兼容性。有关详细信息,请参阅"PADDING OF BASE64 DIGESTS"

参见

摘要Digest::SHA::PurePerl

安全散列标准(FIPS PUB 180-4 草案)可以在以下位置找到:

http://csrc.nist.gov/publications/drafts/fips180-4/Draft-FIPS180-4_Feb2011.pdf

带密钥的散列消息认证码 (HMAC)

http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf

作者

Mark Shelor	<[email protected]>

致谢

作者特别感谢

Gisle Aas
H. Merijn Brand
Sean Burke
Chris Carey
Alexandr Ciornii
Chris David
Jim Doble
Thomas Drugeon
Julius Duque
Jeffrey Friedl
Robert Gilmour
Brian Gladman
Jarkko Hietaniemi
Adam Kennedy
Mark Lawrence
Andy Lester
Alex Muntada
Steve Peters
Chris Skiscim
Martin Thurn
Gunnar Wolf
Adam Woodbury

"谁凭借训练有素的技巧,从如此巨大的波涛和如此浓重的黑暗中拯救了生命,并将其停泊在如此完美的平静和如此灿烂的光明中" - 卢克莱修

版权和许可

版权所有 (C) 2003-2022 Mark Shelor

此库是免费软件;您可以根据与 Perl 本身相同的条款重新分发和/或修改它。

perlartistic