如何使用React和Crypto模块创建一个基于用户输入的哈希文本生成器应用程序

394 阅读10分钟

React.js哈希应用程序生成器

哈希是用一个数学函数将任何长度的输入转化为固定大小的文本字符串。这意味着我们可以通过一种算法将任何文本转换为数字和字母的数组,无论它有多长。被转换/隐藏的文本被称为输入。用来掩盖这个字符串的算法被称为哈希函数。

生成的值被称为哈希值。散列文本也被称为摘要。散列将原始信息,即纯文本,转换为另一种形式,只有授权方才能理解它。

本指南将向读者介绍哈希函数,并说明如何使用React.js建立一个哈希生成器应用程序。我们将创建一个简单的应用程序,从文本字符串中计算哈希值,对其进行哈希处理,并将哈希处理后的文本发回给用户。

前提条件

要跟上这篇文章,请确保你有以下基本要求。

  • 在你的电脑上安装[Node.js]。
  • 一些关于工作的JavaScript和React.js框架的基本知识。
  • 理解密码学的概念。

不同类型的哈希函数

哈希函数,也被称为哈希算法,创建数字指纹和签名。散列函数映射任意的字符串。它把它分解开来。然后这些任意的数据字符串将被映射到一个固定长度的输出。

即使输入字符串的大小改变了,对于一个特定的哈希函数,输出字符串或哈希值仍然是相同的长度。你可以使用不同类型的哈希函数来哈希任何输入值。一些流行的哈希函数包括。

  • 消息摘要(MD)

这是一个产生128位哈希值的哈希函数。它接受任何长度的输入,并作为输出返回一个固定长度的摘要值,用于验证原始信息。不管输入是什么,摘要大小总是128位。MD5被设计为对之前的MD4消息摘要算法的改进。

  • 安全哈希函数(SHA)

安全散列算法,也被称为SHA,是由美国国家安全局(NSA)开发的一个加密散列函数系列,旨在保持数据的安全性。它通过将数据转换为哈希值来做到这一点。它使用一种模块化的算法,接受各种位运算和压缩函数。有不同的SHA系列哈希函数。

这些包括。

  1. SHA-0 - 该算法生成一个160位的字符串值作为哈希值。它发展了一些弱点,其算法没有变得非常流行,SHA-1被设计用来纠正其弱点。

  2. SHA-1 - SHA-1是最广泛使用的一种哈希函数。它被用于各种应用和协议,如安全套接字层(SSL)。2005年,人们发现了一种方法,可以在合理的时间范围内检测SHA-1算法的碰撞。

  3. SHA-2 - SHA-2家族有四个变种,即SHA-224、SHA-25、SHA-256和SHA-512。在这个家族中还没有成功攻击的报告。尽管SHA-2是一个强大的散列函数,它的基本设计仍然是基于SHA-1的。这促使美国国家标准和技术研究所呼吁开发新的有竞争力的散列函数。

  4. SHA-3 - 在2012年10月,美国国家标准协会为SHA-3加密标准采用了Keccak算法。这种算法具有许多优点,如更好的性能和更好的抗攻击能力。

好的哈希函数的特征

  • 它应该很容易将输入转化为其摘要,但反之亦然。

  • 哈希值应该总是看起来是随机的。这意味着,如果你在输入字符串的任何地方改变一个值,整个摘要应该改变,哈希摘要应该改变。在文本的变化和哈希值的变化之间不应该有任何模式。它改变为另一个完全随机的值。

  • 自由碰撞--找到一个与另一个生成的哈希值重复的值,实际上应该是不可能的。

  • 它不应该是昂贵的。一个好的哈希函数应该在计算上是高效的,因为它在应用时应该是实用的。

  • 它应该有能力对不同种类的数据进行散列。例如,尽管本指南对文本进行了哈希,但一个好的哈希函数应该对其他数据输入进行哈希,如文件。有了这个,我们就可以跟踪一个文件是否被修改过。有了这样的属性,你就可以注意到一个文件是否被改变了,因为对该文件的一个比特的改变会产生一个完全不同的哈希值。

加密与哈希

尽管散列函数的过程使用散列算法来生成散列值,但它们主要用于比较,而不是用于加密目的。有一点需要注意的是,散列输出是以公开的方式产生的。因此,所有东西都是公开的。没有保密性。

加密是一种特殊类型的编码,用于传输私人数据。在加密中,要加密的数据使用加密算法,如Rivest-Shamir-Adleman(RSA)使用密码方法进行转换。因此,加密后的数据也被称为密码文本。

与哈希值不同,密码文本可以被解码并转换为实际的原始输入。因此,密码文本有利于数据的私人/秘密共享。在这种情况下,发送方对原始数据进行编码,并将其作为密码文本发送。收件人将解码所发送的密码文本并将其转换为明文,以了解共享信息。

散列数据是不可逆的。例如,当散列被用于登录系统的目的时。一旦用户登录,部分密码就会使用散列算法与数据库进行核对,进行散列。

如果散列键是相同的,用户就会得到登录权限,实现完整性。这些过程都是不可逆的。如果你对一个词、一个密码或文件进行散列,你不能拿着这个散列值,然后找出原来的输入是什么。

密码文本的长度是不同的。一个密码文本的长度取决于被共享的信息的长度。因此,如果信息很长,密码文本将根据输入文本生成。然而,根据所使用的散列函数,散列将始终具有相同的长度。

例如,如果你要用散列函数散列一个单词和一整本书,你仍然会得到相同长度的不同散列值。

使用React.js设置一个哈希生成器

我们将使用create-react-app工具来设置一个React应用。它完成了配置Webpack和Babel的繁重工作,这样你就可以专注于代码来扩展应用程序。

首先,在你的电脑上创建你想要的项目文件夹,然后运行以下命令来启动一个React模板应用程序。

npx create-react-app hash-generator-app

给它几分钟的时间,一旦这个过程完成,应用程序就会被完全设置好。使用以下命令进入创建的项目文件夹。

cd hash-generator-app

然后,通过运行来启动开发服务器。

npm run start

上述命令将在端口3000 上启动开发服务器。一个默认的页面也将从你的默认浏览器中加载,加载一个简单的React Hello world页面。

设置加密技术

如前所述,为了将用户将输入的文本转换为编码文本,我们需要使用散列算法。

在JavaScript中,散列算法是从Crypto模块中使用的。因此,我们需要在我们的应用程序中安装Crypto模块。要做到这一点,请运行以下命令。

npm install crypto-js

从用户输入生成散列文本

我们将首先设置一个用户将添加一些文本的表单。但是,首先,用下面的代码块替换你的src/App.js 文件中的模板代码。

import { useState } from "react";
import './App.css';

function App() {

    // user input text
    const [plain_text, setPlainText] = useState("");

    // submit handler
    const onSubmit = e => {
        e.preventDefault();
    }

    return (
        <div className="App">

            <form className="form" onSubmit={onSubmit}>

                <div className="form-content">

                    <div className="form-group">
                        <label>
                            Sample text
                        </label>
                        <input type="text" placeholder="Enter any text" value={plain_text} onChange={
                            (e) => setPlainText(e.target.value)
                        } />
                    </div>


                    <div className="form-group">
                        <button className="submit-btn" type="submit">
                            Generate hashed
                        </button>
                    </div>

                </div>

            </form>

        </div>
    );
}
export default App;

我们展示的表单有一个供用户输入文本的字段。当用户点击Generate hashed 按钮时,该表单就会被提交。然后像这样编辑src/App.css ,给表单一些样式。

.App {
    text-align: center;
}

.form{
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.form-content{
    padding: 15px;
    box-shadow: 0 1px 3px 0 #d4d4d5, 0 0 0 1px #d4d4d5;
    width: 45%;
    margin: 0px auto;
    text-align: left;
}

.form-group{
    display: block;
    width: 100%;
    margin: 10px 0px;
}

.form-group label{
    display: block;
    width: 100%;
    margin: 5px 0px;
}

.form-group input[type="text"]{
    width: 99%;
    padding: 7px 5px;
}

保存这些修改后,你的页面应该有如下的表单。

generate-hash-form

下一步将涉及到对onSubmit 函数的工作,以哈希用户发送的文本,将其存储在状态中,并显示它。

src/App.js 文件中,导入Crypto模块,为不同的哈希函数设置状态,如下图所示。

import crypto from "crypto-js";

const [aes_hashed_text,setAesHashedText] = useState("");
const [md5_hashed_text,setMd5HashedText] = useState("");
const [sha512_hashed_text,setSha512HashedText] = useState("");
const [sha256_hashed_text,setSha256HashedText] = useState("");
const [sha3_hashed_text,setSha3HashedText] = useState("");

onSubmit 函数中,设置一个密钥,使用不同的算法对文本进行散列,并将每个记录设置为state

const onSubmit = e => {
    e.preventDefaul

    // md5
    setMd5HashedText(
        crypto.MD5(plain_text).toString()
    );

    // sha512
    setSha512HashedText(
        crypto.SHA512(plain_text).toString()
    );

    // sha256
    setSha256HashedText(
        crypto.SHA256(plain_text).toString()
    );

    //sha3
    setSha3HashedText(
        crypto.SHA3(plain_text).toString()
    );

}

这里我们使用的是MD5SHA512SHA256SHA3。随意改变哈希函数为任何你想生成的字符串。

上述所有的算法都使用非对称加密,这意味着它们在散列过程中不使用任何密钥。在所有情况下,我们都要转换为字符串来查看输出。

form-content div 里面的表单中添加以下内容,这样就可以查看生成的散列值。

{
    md5_hashed_text ? (
        <div className="form-group">
            <label>md5</label>
            <div className="hashed-data-content">
                <input type='text' readOnly value={md5_hashed_text} />
                <button type="button" onClick={() => copyToClipboard(md5_hashed_text)}>copy</button>
            </div>
        </div>
    ) : null
}

{
    sha512_hashed_text ? (
        <div className="form-group">
            <label>SHA512</label>
            <div className="hashed-data-content">
                <input type='text' readOnly value={sha512_hashed_text} />
                <button type="button" onClick={() => copyToClipboard(sha512_hashed_text)}>copy</button>
            </div>
        </div>
    ) : null
}

{
    sha256_hashed_text ? (
        <div className="form-group">
            <label>SHA256</label>
            <div className="hashed-data-content">
                <input type='text' readOnly value={sha256_hashed_text} />
                <button type="button" onClick={() => copyToClipboard(sha256_hashed_text)}>copy</button>
            </div>
        </div>
    ) : null
}

{
    sha3_hashed_text ? (
        <div className="form-group">
            <label>SHA3</label>
            <div className="hashed-data-content">
                <input type='text' readOnly value={sha3_hashed_text} />
                <button type="button" onClick={() => copyToClipboard(sha3_hashed_text)}>copy</button>
            </div>
        </div>
    ) : null
}

src/App.css 中添加以下样式,以格式化显示的散列值。

.hashed-data-content{
  width: 100%;
  display: flex;
  justify-content: space-between;
}

确保开发服务器仍在运行,刷新浏览器的标签。如果服务器没有运行,开始使用npm run dev ,在浏览器中打开http://localhost:3000/ 。填入一个样本文本,然后点击Generate hash 按钮。你应该能够看到如下所示的哈希文本。

generated-hash-form-with-output

结论

要被认为是加密安全的,哈希函数应该是攻击者不可能生成与特定哈希值相匹配的信息。明文的轻微变化应该在两个摘要中引发巨大的差异。

这样一来,攻击者就不可能创建两个产生相同哈希值的信息。因此,没有办法重新生成明文。

在这篇文章中,我们学习了如何使用React和Crypto模块创建一个基于用户输入的哈希文本生成器应用程序。