SHA-3(安全散列算法3)



信息安全技术的新模型被称为SHA-3。这是一段代码,可以加密信息并使其对任何没有密钥的人不可读。SHA-1和SHA-2等先前版本中的基本功能与SHA-3不同。

SHA-3是称为Keccak的一组更大的秘密代码工具的一部分。该小组由Guido Bertoni、Joan Daemen、Michael Peeters和Gilles Van Assche等人创建,他们在名为RadioGatun的基础上进行了构建。他们让Keccak执行更多操作,例如为消息创建秘密代码,并在通过互联网发送信息时保护信息安全。

Keccak以一种称为海绵构造的独特方式工作。它就像一块海绵,可以吸收任意数量的水(或数据),也可以挤出任意数量的水。它可以混合数据,以便在没有密钥的情况下没有人能够理解它。这使得它非常灵活和有用。

尽管SHA-3相对较新,但较旧的算法SHA-1和SHA-2仍在使用。但如果需要,SHA-3可以直接替换它们。SHA-3的目标是使秘密代码更强大,并总体上更好。

对于小型消息,有一个名为KangarooTwelve的更快版本。它可以更快地处理短消息,并且具有特殊的设置使其工作得更好。

SHA-3系列有六个哈希函数,其摘要(哈希值)为128、224、256、384或512位:SHA3-224、SHA3-256、SHA3-384、SHA3-512、SHAKE128和SHAKE256。

此库与上面列出的每种算法兼容。

  • SHA3-224,28位摘要大小
  • SHA3-256,32位摘要大小
  • SHA3-384,48位摘要大小
  • SHA3-512,64位摘要大小
  • SHAKE-128
  • SHAKE-256

SHA-3的历史

Keccak算法基于早期称为PANAMA和RadioGatun的算法,由Guido Bertoni、Joan Daemen、Michael Peeters和Gilles Van Assche开发。Daemen和Craig Clapp于1998年创建了PANAMA。后来,在2006年,Daemen、Peeters和Van Assche推出了RadioGatun,这是PANAMA的升级版本。

美国国家标准与技术研究院(NIST)于2006年发布了一场竞赛,以扩展SHA-3,这是一种广为人知的秘密代码。以前的秘密算法(如MD5、SHA-0和SHA-1)不再安全,因此为了为SHA-2提供机会,进行了此操作。

Keccak是竞赛的51个参赛作品之一。在经过几轮测试和改进后,它于2010年12月进入决赛。在竞赛期间,Keccak进行了修改以提高其强度和安全性。

2012年10月2日,Keccak被选中作为竞赛的支持者。NIST于2014年发布了FIPS 202“SHA-3标准:基于置换的哈希和可扩展输出函数”的草案。该草案于2015年8月5日获得批准,使SHA-3成为正式的哈希标准。

SHA-3的设计

SHA-3的设计使用一种称为海绵构造的方法。以下是它的工作原理:

  • 吸收阶段 - 在此步骤中,“海绵”吸收信息。一个称为f的转换函数用于将每块数据与海绵当前状态的一部分组合。此函数重新排列状态的组件。“速率”指的是状态与输入/输出交互的程度,而“容量”指的是保持不变的状态的程度。系统的安全性取决于其容量。
  • 挤压阶段 - 在挤压阶段,转换函数f在从状态的同一子集中读取输出块之间交替。要修改输出的长度,请更改函数的参数。

SHA-3的内部状态是一个单词网格,每个单词都有固定数量的位。此网格的大小影响算法的整体安全性。SHA-3的不同版本允许不同的输出长度和字大小,使其适合各种安全需求。

一些SHA-3示例(如SHA3-224、SHA3-256、SHA3-384和SHA3-512)的输出长度小于速率,因此在挤压阶段不需要额外的转换。但是,对于SHAKE128和SHAKE256等版本(允许不同的输出长度),需要进行更多更改才能产生所需的结果。

Sponge Construction

以下是海绵构造的工作原理概述:

  • 输入字符串N用一个名为pad的函数进行填充。这确保了填充字符串P的长度可以被速率r整除,表示为len(P)/r = n,其中len(P)是P的长度。
  • 然后,填充字符串P被分成n个连续的块,每个块包含r位。这些块被标识为P0、P1、...和Pn-1
  • 状态S被初始化为b个零位字符串,其中b是状态的总宽度。
  • 每个块Pi都在末尾扩展了一个c个零位字符串,其中c等于b - r。这将创建一个长度为b的块。然后,此扩展块与当前状态S进行异或运算。之后,将块置换函数f应用于结果以生成新的状态S。
  • 输出字符串Z被设置为空字符串。当Z的长度小于d(所需的输出长度)时,当前状态S的前r位将添加到Z中。如果Z仍然小于d位,则f将再次应用于S以生成新的状态S。此操作将持续进行,直到Z达到所需的长度d。
  • 最后,如果Z大于d位,则将其截断以获得最终结果。

在SHA-3中,内部状态S被定义为5×5的单词网格,每个单词宽w位。在SHA-3中,w设置为64,总状态大小为1600位(5×5×64 = 1600)。

但是Keccak允许各种字大小,从w = 1位开始,总状态大小为25位。字大小的灵活性使得能够使用较小的状态大小测试密码分析攻击,以及使用从w = 8(200位)到w = 32(800位)的中间状态大小的实际实现。

在一些SHA-3实现中,例如SHA3-224、SHA3-256、SHA3-384和SHA3-512,速率r(用于吸收输入的状态部分)大于所需的输出长度d。在这些情况下,在挤压步骤期间不需要进行进一步的块置换。相反,状态的前d位给出了所需的哈希输出。

另一方面,SHAKE128 和 SHAKE256 允许任意长度的输出。此功能在诸如最优非对称加密填充之类的应用中非常有用,在这些应用中,输出长度必须自定义以满足特定要求。

SHA-3 变体的示例

假设我们有一个明文为“Tutorialspoint”,那么根据 SHA-3 变体的哈希值如下所示:

SHA3-224

此变体生成一个 224 位的哈希值。“Tutorialspoint” 的哈希值为 - b3b059b134b17b4bed361b16392b40b16648695eabbf87896c0f8e50

SHA3-256

此变体生成一个 256 位的哈希值。“Tutorialspoint” 的哈希值为 - a789f0a2eb3b13ec69245210b8c522bbb7c33ccb0561729697294bcd35367622

SHA3-384

此变体生成一个 384 位的哈希值。“Tutorialspoint” 的哈希值为 - 68ccee414159dc755f8aa17d82bd1958c956cd09ecf9a221b661c93ce7b36e40237cbadddf48a0600e1eda4ecdd87295

SHA3-512

此变体生成一个 512 位的哈希值。“Tutorialspoint” 的哈希值为 - fb3e821c3a16c720f1137673c6d4247f26e88889093831cf4ca2bb1ef7e0ce4566798297d891b5fae396e93fe4b7003be794e18a194e438a1c802798d0703819

SHAKE128

哈希值:42a52efbca7de46de5ab54b443870c48

SHAKE256

哈希值06c9b7ff87b0d9360f0a2e0d2fe58757945f79b8d7b5e7a2a14827c8d37ff570

这些变体提供了不同级别的安全性和输出长度,以满足各种加密需求。上述哈希值是使用不同的 SHA-3 变体对明文“Tutorialspoint”进行的唯一表示。

此外,还有 SHAKE128 和 SHAKE256,它们允许任意长度的输出,这使得它们适用于需要灵活哈希长度的应用程序。

各种 SHA 函数的比较

函数 输出大小 安全性 用途
SHA-1 160 位 容易受到碰撞攻击,不再被认为是安全的 遗留系统,但应避免在新设计中使用
SHA-2(SHA-224、SHA-256、SHA-384、SHA-512) 分别为 224、256、384 和 512 位 通常被认为是安全的,并且能够抵抗碰撞攻击 数据完整性验证、数字签名、加密应用
SHA-3(SHA3-224、SHA3-256、SHA3-384、SHA3-512) 分别为 224、256、384 和 512 位 旨在提供针对已知加密攻击的安全保障 SHA-2 的替代方案,需要加密散列的新设计
SHAKE128 和 SHAKE256 可变(可以生成任何所需长度的哈希值) 旨在提供与 SHA-3 类似的安全保障 需要灵活的哈希长度,加密协议需要动态哈希长度

使用 Python 实现 SHA-3

Python 代码计算给定消息在各种哈希长度(224、256、384 和 512 位)下的 SHA-3 哈希值。因此,我们将使用 Python 的 hashlib 包,该包提供安全的哈希和消息摘要方法。它包含各种加密哈希方法的实现,例如 SHA-3。它检查长度是否为 224、256、384 或 512 位,然后使用正确的 hashlib.sha3_224()、hashlib.sha3_256()、hashlib.sha3_384() 或 hashlib.sha3_512() 函数计算哈希值。因此,各种 SHA-3 变体的 Python 代码如下所示:

import hashlib

def sha3(message, length):
   if length == 224:
      return hashlib.sha3_224(message.encode()).hexdigest()
   elif length == 256:
      return hashlib.sha3_256(message.encode()).hexdigest()
   elif length == 384:
      return hashlib.sha3_384(message.encode()).hexdigest()
   elif length == 512:
      return hashlib.sha3_512(message.encode()).hexdigest()
   else:
      return "Invalid length"

message = "Tutorialspoint"
print("SHA3-224 hash:", sha3(message, 224))
print("SHA3-256 hash:", sha3(message, 256))
print("SHA3-384 hash:", sha3(message, 384))
print("SHA3-512 hash:", sha3(message, 512))

输出

SHA3-224 hash: b3b059b134b17b4bed361b16392b40b16648695eabbf87896c0f8e50
SHA3-256 hash: a789f0a2eb3b13ec69245210b8c522bbb7c33ccb0561729697294bcd35367622
SHA3-384 hash: 68ccee414159dc755f8aa17d82bd1958c956cd09ecf9a221b661c93ce7b36e40237cbadddf48a0600e1eda4ecdd87295
SHA3-512 hash: fb3e821c3a16c720f1137673c6d4247f26e88889093831cf4ca2bb1ef7e0ce4566798297d891b5fae396e93fe4b7003be794e18a194e438a1c802798d0703819

使用 Java 实现 SHA-3

为了实现 SHA-3 变体,我们将使用 Java 上的内置类 - java.security.MessageDigest 和 java.security.NoSuchAlgorithmException。MessageDigest 类用于加密哈希函数。它提供了 SHA-3 等算法以进行安全散列。代码展示了如何使用 Java 的 MessageDigest 类计算给定不同长度消息的 SHA-3 哈希值。它将哈希字节更改为十六进制表示形式。因此,Java 中 SHA-3 的代码如下所示:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Sha3Algorithm {
   public static String sha3(String msg, int length) throws NoSuchAlgorithmException {
      MessageDigest digest = MessageDigest.getInstance("SHA3-" + length);
      byte[] hashBytes = digest.digest(msg.getBytes());
      StringBuilder hexString = new StringBuilder();
      for (byte hashByte : hashBytes) {
         String hex = Integer.toHexString(0xff & hashByte);
         if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
      }
      return hexString.toString();
   }

   public static void main(String[] args) throws NoSuchAlgorithmException {
      String msg = "Tutorialspoint";        
      System.out.println("SHA3-224 hash: " + sha3(msg, 224));
      System.out.println("SHA3-256 hash: " + sha3(msg, 256));
      System.out.println("SHA3-384 hash: " + sha3(msg, 384));
      System.out.println("SHA3-512 hash: " + sha3(msg, 512));
   }
}

输出

SHA3-224 hash: b3b059b134b17b4bed361b16392b40b16648695eabbf87896c0f8e50
SHA3-256 hash: a789f0a2eb3b13ec69245210b8c522bbb7c33ccb0561729697294bcd35367622
SHA3-384 hash: 68ccee414159dc755f8aa17d82bd1958c956cd09ecf9a221b661c93ce7b36e40237cbadddf48a0600e1eda4ecdd87295
SHA3-512 hash: fb3e821c3a16c720f1137673c6d4247f26e88889093831cf4ca2bb1ef7e0ce4566798297d891b5fae396e93fe4b7003be794e18a194e438a1c802798d0703819
广告