本文介绍了确定性和非确定性密钥交换的概念,以及如何在 ECDH 密钥交换方法中使用 libsodium.js 实现这两种方式。确定性密钥交换使用已知的种子值生成密钥,每次都得到相同的结果,而非确定性密钥交换则随机生成密钥,每次结果都不同。文章通过代码示例展示了这两种方法的实现,并提供了在线演示。
如果你从事网络安全工作,你是否了解确定性密钥生成和非确定性密钥生成之间的区别?嗯,对于确定性,当我们运行代码时,我们总是得到相同的密钥生成,而对于非确定性,每次我们都会得到一组不同的密钥创建,因此无法猜测密钥是什么。这种事情发生在签名中,我们可以知道对于给定的密钥集我们会得到什么签名(确定性签名),或者不能(非确定性)。如果你有兴趣,ECDSA 是一种非确定性签名方法(因为它使用随机 nonce 值),而 EdDSA 和纯 RSA 签名通常是确定性的。
基本上,密钥交换方法的确定性都归结于我们生成密钥的方式。如果我们对这些使用已知的种子值,我们将总是得到相同的密钥。否则,如果密钥是随机生成的,我们将得到一个非确定性的结果。
在这种情况下,我们将使用 libsodium.js 来实现 ECDH 密钥交换方法,它实现了 WASM 集成。
使用 ECDH(椭圆曲线 Diffie-Hellman)方法,Alice 生成一个 a 的秘密,并计算一个公钥点 a. G,其中 G 是椭圆曲线上的一个基点。Bob 生成一个 b 的秘密,并计算一个公钥点 b. G。他们交换他们的公共值,Alice 收到 b. G,Bob 收到 a. G。接下来,Alice 将计算 a.(b. G),Bob 将计算 b.(a. G)。这些值应该相同。使用确定性密钥交换,Bob 和 Alice 都将使用一个秘密种子值来每次生成相同的密钥,因此对于给定的种子值集,我们将总是能够生成所需的共享秘密:
因此,如果我们为 Bob 和 Alice 的密钥生成使用一个定义明确的种子值,我们总是会得到相同的共享密钥。如果任何密钥是随机生成的,我们每次都会得到不同的密钥。
对于非确定性密钥交换,我们将有 [ 这里]:
const BobKeyypair = sodium.crypto_kx_keypair();
const BobSecret = BobKeyypair.privateKey;
const BobPublic = BobKeyypair.publicKey;
const AliceKeyypair = sodium.crypto_kx_keypair();
const AliceSecret = AliceKeyypair.privateKey;
const AlicePublic = AliceKeyypair.publicKey;
const Aliceshared = sodium.crypto_kx_client_session_keys(BobPublic, BobSecret, AlicePublic);
const Bobshared = sodium.crypto_kx_server_session_keys(AlicePublic, AliceSecret, BobPublic);
对于这个,每次我们生成新的密钥,我们都会得到一个新的共享密钥:
对于确定性,请参阅使用种子值或短语 [ 这里]:
const str1 = sodium.from_string(document.getElementById("Bobseed").value);
const str2 = sodium.from_string(document.getElementById("Aliceseed").value);
const Bobseed = sodium.crypto_generichash(sodium.crypto_kx_SEEDBYTES, str1);
const BobKeyypair = sodium.crypto_kx_seed_keypair(Bobseed);
const BobSecret = BobKeyypair.privateKey;
const BobPublic = BobKeyypair.publicKey;
const Aliceseed = sodium.crypto_generichash(sodium.crypto_kx_SEEDBYTES, str2);
const AliceKeyypair = sodium.crypto_kx_seed_keypair(Aliceseed);
const AliceSecret = AliceKeyypair.privateKey;
const AlicePublic = AliceKeyypair.publicKey;
const Aliceshared = window.sodium.crypto_kx_client_session_keys(BobPublic, BobSecret, AlicePublic);
const Bobshared = window.sodium.crypto_kx_server_session_keys(AlicePublic, AliceSecret, BobPublic);
有了这个,对于相同的种子短语值将总是生成相同的 resultant key。对于“Bob”和“Alice”的短语,我们得到密钥:
这是演示:
和:
如果你有兴趣,这里有一些其他的 Web 集成用于密码学:
使用 JavaScript 的 Web 密码库 \ \ JavaScript 代码允许在浏览器中执行,而不是在服务器上执行。 它通常比运行的代码更快…\ \ asecuritysite.com
- 原文链接: billatnapier.medium.com/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!