密码学 - SHA 算法



SHA 代表安全散列算法。数据和证书使用 SHA(MD5 的修改版本)进行散列。散列算法使用按位运算、模加法和压缩函数将输入数据压缩成更小、更难以理解的形式。您可能会问散列是否可以被破解或解码。散列是单向的,这意味着一旦数据被散列,就需要进行暴力攻击才能破解生成的散列摘要。这是散列与加密的主要区别。

查看下面的图片,了解 SHA 算法的工作原理。即使消息中的单个字符发生变化,SHA 也旨在提供唯一的散列。

SHA Algorithm

散列两个相似但不同的消息,例如“Heaven”和“heaven is different”,就是一个例子。然而,唯一的区别是一个小写字母和一个大写字母。

SHA 还帮助识别对原始消息所做的任何更改。用户可以通过将散列摘要与原始散列摘要进行比较来确定是否更改了单个字母,因为它们会有很大的不同。SHA 的关键特性之一是其确定性。这意味着只要知道使用的散列算法,任何计算机或用户都可以重现散列摘要。由于 SHA 的有限性,互联网上所有 SSL 证书都必须使用 SHA-2 方法进行散列。

SHA 类型

SHA 代表安全散列算法系列的加密散列函数。每种 SHA 类型都是不同的,并且有一系列数字。以下是一些常见的类型 -

  • SHA-1 - 这是 SHA 的第一个版本。由于这些弱点,目前认为它安全性较低。
  • SHA-2 - 这包括几种具有不同摘要大小的散列算法,例如 SHA-224、SHA-256、SHA-384 和 SHA-512。它们比 SHA-1 更安全,并且经常使用。
  • SHA-3 - SHA 系列的新成员,它是使用与 SHA-1 和 SHA-2 不同的方法创建的。它们包括 SHA3-224、SHA3-256、SHA3-384 和 SHA3-512。

每种 SHA 都根据输入数据生成唯一的散列值(固定长度的字符串)。这些散列值用于生成数字签名和数据完整性验证等其他安全相关任务。

SHA 的特性

对于密码学,安全散列算法或 SHA 由于以下几个重要原因而有用 -

  • 数据完整性 - SHA 根据任意大小的输入数据生成固定大小的散列结果(通常为 160、256、384 或 512 位)。由于输入数据中的微小变化会导致散列值发生显着变化,因此它可用于验证数据的完整性。如果散列值匹配,则表明输入数据未被更改。
  • 唯一性 - SHA 尝试为一系列输入生成唯一的散列结果。虽然在理论上仍然可能,但现代 SHA 版本(例如 SHA-256 和 SHA-3)旨在降低两个不同的输入生成相同散列值(冲突)的可能性。
  • 加密安全性 - SHA 旨在处理原像、第二原像、冲突和其他类型的加密攻击。这意味着攻击者将难以确定导致相同散列值的两个不同输入,或者根据其散列值反向工程原始输入数据。
  • 效率 - SHA 算法可以快速生成散列值,即使对于大量输入数据也是如此,因为它们在计算上是高效的。
  • 广泛使用 - SHA 广泛用于许多安全应用程序中,例如区块链技术、数字签名、消息认证码 (MAC) 和密码散列。

实现

现在我们将使用 Python、Java 和 C++ 实现 SHA 算法 -

使用 Python 实现

首先,我们将使用 Python 的 hashlib 库来为给定的输入字符串计算 SHA 散列。这里可以根据您的需要选择 SHA 的特定版本。使用 Python 的代码如下 -

示例

import hashlib

def calculate_sha(input_data):
   sha_hash = hashlib.sha256()  # Choose different versions sha1(), sha224(), sha384(), etc.
   sha_hash.update(input_data.encode('utf-8'))
   return sha_hash.hexdigest()

input_data = "Hello, Tutorialspoint!"
sha_hash = calculate_sha(input_data)
print("SHA hash:", sha_hash)

以下是上述示例的输出 -

输入/输出
SHA hash: caba24f8a70cc24277bffcc27aa952723fbf369f315b9657eebf7c7e42b7a1f9

使用 Java 实现

现在我们将使用 Java 的 MessageDigest 库来为给定的输入字符串计算 SHA 散列。使用 Java 的代码如下 -

示例

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

public class SHAExample {
   public static void main(String[] args) {
      String input = "Hello, Everyone!";
      try {
         MessageDigest shaDigest = MessageDigest.getInstance("SHA-256"); // Choose different versions like "SHA-1", "SHA-224", "SHA-384", etc.
         byte[] hashBytes = shaDigest.digest(input.getBytes());
         StringBuilder sb = new StringBuilder();
         for (byte b : hashBytes) {
            sb.append(String.format("%02x", b));
         }
         String shaHash = sb.toString();
         System.out.println("SHA hash: " + shaHash);
      } catch (NoSuchAlgorithmException e) {
         e.printStackTrace();
      }
   }
}

以下是上述示例的输出 -

输入/输出
SHA hash: 06b1f0e2138fdb9f0ae8b37cb7a0c77e9e9af1293aa1bfb4d17e57a36542348c

散列的未来

SHA-2 现在是散列算法的行业标准,但 SHA-3 可能会在将来取代它。SHA-3 于 2015 年由 NIST 发布,NIST 也创建了 SHA-1 和 SHA-2。虽然,由于多种原因,它从未被接受为行业标准。当 SHA-3 发布时,大多数组织已经从 SHA-1 切换到 SHA-2,因此在 SHA-2 仍然非常安全的情况下切换到 SHA-3 毫无意义。

此外,这并不完全正确,SHA-3 被认为比 SHA-2 慢。SHA-3 每年都在进步,虽然它在软件中速度较慢,但与 SHA-1 和 SHA-2 相比,它在硬件中速度更快。

雪崩效应

使用 SHA-1 对原始消息'Heaven'进行散列的散列摘要为“06b73bd57b3b938786daed820cb9fa4561bf0e8e”。使用 SHA-1 对第二个'heaven'(类似的消息)进行散列的散列摘要如下所示:“66da9f3b8d9d83f34770a14c38276a69433a535b”。我们将这种现象称为雪崩效应。这种效应对于密码学至关重要,因为它意味着对输入消息的任何修改都可能显着改变结果。通过这样做,将阻止攻击者破译散列摘要的原始含义,并向消息的接收者通知在传输过程中所做的任何修改。

广告