本文探讨了后量子密码(PQC)签名迁移的启动,重点介绍了ML-DSA(又名Dilithium)作为RSA、ECDSA和EdDSA等传统签名算法的潜在替代方案。文章通过OpenSSL和Botan3库的代码示例,展示了ML-DSA的集成和应用,并对密钥生成速度和签名验证进行了测试。

不管你喜不喜欢,互联网信任的核心是基于公钥方法。有了这个,Bob 通过用他的私钥签署消息的哈希来证明他的身份和消息的完整性:

然后 Alice 使用 Bob 的公钥验证签名。这种方法通过 PKI(公钥基础设施)集成到互联网中,我们可以为 Alice 提供对 Bob 公钥的高度信任。这通常采用包含 Bob 公钥的 X.509 数字证书的形式。实际上,每次我们连接到网站时,浏览器都会检查传递的消息上的数字签名,并根据网站的公钥进行检查。
因此,我们已经发展出 RSA、ECDSA 和 EdDSA 这三个主要的 FIPS 186(数字签名标准)批准的签名。在互联网上,我们主要仍然使用 RSA 签名,但在许多其他领域,例如区块链,ECDSA 和 EdDSA 提供了更轻量级的签名。
但是,Shor 表明 RSA、ECDSA 和 EdDSA 都可以通过大规模构建的量子计算机破解。因此,主要的迁移将是朝着 ML-DSA(又名 Dilithium)方向发展:

在密钥对生成速度方面,ML-DSA-44 的性能与 ECDSA 或 Ed25519(基准测试中最快的)不太一样,但比 RSA 和 SLH-DSA 快:
Ed25519 26090 keygen/sec;
ECDSA-secp256r1 19531 keygen/sec;
Ed448 1636 keygen/sec;
ML-DSA-4x4 5123 keygen/sec;
RSA-2048 13 keygen/sec;
SLH-DSA-SHA2-128s 6 keygen/sec;
SLH-DSA-SHA2-128s 0 sign/sec;
将 ML-DSA 集成到互联网中的一个核心进展是 OpenSSL 3.5 的发布。代码实现见[ here]:
##include <stdio.h>
##include <string.h>
##include <stdlib.h>
##include <openssl/evp.h>
##include <openssl/pem.h>
##include <openssl/err.h>
##include <openssl/core_names.h>
##include <openssl/params.h>
##include <openssl/ec.h>
static void hexdump(const char *label, const unsigned char *buf, size_t len) {
printf("%s (%zu bytes): ", label, len);
for (size_t i = 0; i < len; i++) printf("%02X", buf[i]);
printf("\n");
}
static EVP_PKEY *generate_keys(unsigned char *type) {
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new_from_name(NULL, type, NULL);
EVP_PKEY_keygen_init(kctx);
EVP_PKEY_keygen(kctx, &pkey);
printf("Type: %s\n\n",type);
uint8_t pub[2592], priv[4896];
size_t priv_len, pub_len;
EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
priv, sizeof(priv), &priv_len);
EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
pub, sizeof(pub), &pub_len);
printf("Private key length: [%d]\n",priv_len);
if (priv_len>500) hexdump("Private key (truncated to 500 bytes):",priv,500);
else hexdump("Private key:",priv,priv_len);
printf("\nPublic key length: [%d]\n",pub_len);
if (pub_len>500) hexdump("Public key (truncated to 500 bytes):",pub,500);
else hexdump("Private key:",pub,pub_len);
EVP_PKEY_CTX_free(kctx);
return pkey;
}
void do_sign(EVP_PKEY *pkey, unsigned char *msg, size_t msg_len,unsigned char *type )
{
size_t sig_len;
unsigned char *sig = NULL;
const OSSL_PARAM params[] = {
OSSL_PARAM_octet_string("context-string", (unsigned char *)"Context string", 33),
OSSL_PARAM_END
};
EVP_PKEY_CTX *sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
EVP_SIGNATURE *sig_alg = EVP_SIGNATURE_fetch(NULL, type, NULL);
EVP_PKEY_sign_message_init(sctx, sig_alg, params);
/* Get size of signature */
EVP_PKEY_sign(sctx, NULL, &sig_len, msg, msg_len);
sig = OPENSSL_zalloc(sig_len);
EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len);
printf("\nMessage: [%s]\n",msg);
printf("\nSignature length: [%d]\n",sig_len);
if (sig_len>500) hexdump("Signature (truncated to 500 bytes):",sig,500);
else hexdump("Signature:",sig,sig_len);
OPENSSL_free(sig);
EVP_PKEY_CTX_free(sctx);
}
int main(int argc, char** argv) {
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
unsigned char *type="mldsa87";
unsigned char *msg="Hello";
int msg_len=5;
if (argc > 1) type = argv[1];
if (argc > 2) msg = argv[2];
EVP_PKEY *key = generate_keys(type);
do_sign(key, msg, strlen(msg),type);
return EXIT_SUCCESS;
}
另一种选择是使用 Botan3 库,它通过[ here]实现:
##include <botan/auto_rng.h>
##include <botan/pk_algs.h>
##include <botan/pubkey.h>
##include <botan/hex.h>
##include <botan/pkcs8.h>
##include <botan/x509_key.h>
##include <iostream>
##include <string>
##include <vector>
int main(int argc, char *argv[]){
int mode =0;
mode = atoi( argv[2]);
std::string plaintext(argv[1]);
auto m="ML-DSA-4x4";
if (mode==0) { m="ML-DSA-4x4"; std::cout << "ML-DSA-4x4";}
else if (mode==1) {m="ML-DSA-6x5"; std::cout << "ML-DSA-6x5";}
else { m="ML-DSA-8x7"; std::cout << "ML-DSA-8x7";}
Botan::AutoSeeded_RNG rng;
auto priv_key = Botan::create_private_key("ML-DSA", rng, m);
auto pub_key = priv_key->public_key();
std::vector<uint8_t> msg(plaintext.begin(), plaintext.end());
Botan::PK_Signer signer(*priv_key, rng, "",Botan::Signature_Format::Standard);
auto signature = signer.sign_message(msg, rng);
auto sig = Botan::hex_encode(signature, true);
std::cout << "\nMessage: " << plaintext << "\n";
std::cout << "\nCiphertext (first 128 bytes out of " << sig.length()/2 << "): " << sig.substr(0, 256) << "\n";
// Encode keys into PEM
const std::string priv_pem = Botan::PKCS8::PEM_encode(*priv_key);
const std::string pub_pem = Botan::X509::PEM_encode(*pub_key);
std::cout << "\nAlice's private key (PKCS#8 PEM):\n" << priv_pem << "\n";
std::cout << "\nAlice's public key (SPKI PEM):\n" << pub_pem << "\n";
// Signature verification
Botan::PK_Verifier verifier(*pub_key, "",Botan::Signature_Format::Standard);
bool ok = verifier.verify_message(msg, signature);
std::cout << "\nVerification (with public key): " << (ok ? "Signature verified" : "Signature not verified") << "\n";
const auto pub_bytes = pub_key->public_key_bits();
std::cout << "\nAlice's public key size: " << pub_bytes.size() << "\n";
return 0;
}
这给出了一个测试运行[ here]:
ML-DSA-4x4
Message: Hello
Ciphertext (first 128 bytes out of 2420): 2E1F9B48790B7653F624A28BA804F0C6F6A554E177815CDA58FF75C15397F0D7FC68DF7B124059044DBE6FA312DC773AA6B212999E24C40687A288FFC065CEF9016FEA87DD54F5B6D6FEC1B6DE25214E318B4EB09DAED03D4F2C20473CA9BC06A72C53B0ECA539F605FBDFE3CBC440F6231255C4156CAEDD58BB2DDDE4AA51D5
Alice's private key (PKCS#8 PEM):
-----BEGIN PRIVATE KEY-----
MDICAQAwCwYJYIZIAWUDBAMRBCCmT74sysrwOYfRI1oowQxwjfJ4Bqp2gBTGLMsL
aL3+VQ==
-----END PRIVATE KEY-----
Alice's public key (SPKI PEM):
-----BEGIN PUBLIC KEY-----
MIIFMjALBglghkgBZQMEAxEDggUhAAwpchiPb4MqMpOY2OYD1bE4H/1/fbSNdow1
8inZCeMtRxcXbNV61ZZjWE28FRFexNMbnR76Ycct6SgW5E/tA0YiD8TVjwz4CKaI
9MCzkxcGdZXKrX7iNR/I7iKTAvHJ8y7+85XSUbUlA/NClaX28fb4x+lotT/TyPv6
u+m7gdO1HcQ67nbcCP2+JYZiQ6DLYey4tEWB81KA6Tojm6hwB3E75gWId6b9iVKf
konJDaB303tDviNZzLhqsVQ0hwcsPwjHr4EUc7FX8I+o4ygnhyM2knIZ2e1wwTNm
4mSU7a5ExVwNiBRi2NOE/O6TuPgJ6wEGFsBCG6WF1K75axXqzQW0WGKeZI0BR55N
Md/qJ7UJOoi4tqO2OV1FQmt0bKCC0ehGCCk2jycguXN1iWMbGgIYVjEKSFQUie2X
8bntHCm35iXTbCe8kqZepMpE5bHpbnVRgSH7vS7AyrGG4mXRGaP/aqCGPeFpJoKj
mtgI5T4mpigLUL+lU9cYf8Pt+dxuJeOXWGqsdRIJuxzGXJVl5gqkZcU1hhpQQRwq
axVjBkH3BVD26ER0dgYbQzoNzRbt17aE8j8X69MX8dYq+5WJ66spMjF3Ps1tu7gF
jhfoSIgLHUI6jjKH+6XG+fDtQjRz1OnSo+xUUzoFqIX5zpZQ+d2VtnathjoF+waE
ab36CxWCaXVvvWe4axWZWxHpTlavm2q5BXwhsFdEXWeuTSE6Y3swRON6dyaZTljU
vJrlxerE5dWvVGxfnWON4MJtb9dem+BRNDAAjtY42F21byFnl0V5Q8jjdgt2euoe
GSkgF/HAvyApya/O2CHEqkygy5bkk9loptWqQjQz4LLvsJkgg8Gh0Qq+leygf6wd
q/Epf1VGLvFTAqfbh57eIW139SqPZBzMrUtk43tqr5+Ej5NXMJ0pjD8uQaoVEWkO
rMh8FKPz5KHuwp0+7xofeyy3NDfQxLUug/hyRjtsaDZV6xE5UuQcoaHQLKrNaAw0
AI8YiyL/wYNCnU3c0+K4wn4cJl6wFfNuy1M4y5GlKkjRScKstI38LoWu1BFrW9yG
Fw/TH4A1GBMpqwv3mLbBBowOkqzAJAi6V/p1xi/UrpKfZypwFpUdDTKfLXo5yfbP
aUGTgaBRTujGhpcix3JDhDwSvNrC257HzZmiYxAL1zFat5GkRAB2uY0Dy57jION4
8yWo59aqnUvsapSbujkCyZik4uPQJ/Xaj1C8JhFQEKKapLZVPn4aLRqCyaPvYB75
P8TFt2kwG4oJR1sS69jYNmDKVZ5tv0tRX1gvlsSFqBu7NAzZydLnlGVtv0gYDhnb
XN1WJpqFfT2wJKKdHVJBN6+RHgUqwsrGxtZc67TJl9H9ex5ijLkuYz3Llfd+hS0G
xwyNUKJC5qahac73+3FO2qkx0ASub8HRZg9KinqMQzWVQZPw2Kiz7ydbyzQ+RfSv
ClSp+op5znqtj4im7d2U45TjLuK3tO4gDWGjuPS9GvUqBl10su+45G52olWGBeMr
g8WvdLoPbcwoGzw0lAg1U2f6s8/vSUh3hmoR8+HssdBLb9LVRoeyDZ+8o5W3xB9I
dynQbI+WDARyugACMkI4xuOlgYENFx2Jr7DgU2q0H6mAAo1jFRw3zdtPIJDLEgnL
MrUU6PmKMXGqg1DXle2hV66y4yaKVyRuAiinklw+tQmLuxZdrBgY72mRwXvHe3Uw
6UTNA9WpXh70aqflXgXsxU04pnZR0PNc5kWoCOnnKdoWa0hWvlY=
-----END PUBLIC KEY-----
Verification (with public key): Signature verified
Alice's public key size: 1312
和 ML-KEM 768 [ here]:
ML-KEM 768
Bob's shared secret: 66868A404EC6947F1183CB6C351447E210DD5F57F106F35B280A83A88043355C
Alice's shared secret: 66868A404EC6947F1183CB6C351447E210DD5F57F106F35B280A83A88043355C
Ciphertext (first 64 bytes out of 2176): 281AAAED1CED520476574FC9ADCA1F9DFE3492ABE9B86F05911C0A8FC52F75D28EA8245A28A11A7995A5032D6ADF9DEEE598DC1E68135D0080174F5E0F01D099
Alice's private key:
-----BEGIN PRIVATE KEY-----
MFICAQAwCwYJYIZIAWUDBAQCBEDyiuJQLmCK/rnTPwikTrxFxN0mkN9gWdvppG4O
VijkHEkkNhIhxcHvIkI166rADd/nUhehIUyIAvUwWwKKYdfb
-----END PRIVATE KEY-----
Alice's public key:
-----BEGIN PUBLIC KEY-----
MIIEsjALBglghkgBZQMEBAIDggShAObTxzjbDJAasYPsBQTlvRB8EScqcN67N9Pb
UepkWH17yrs4S/q3YQrSr6tlPEASdGN7NZT5tOLDj5LmVYzguYszorDCU9Iwc6pE
DbZkGME5MzYWCfexQuoxwK8ajX3rMZocjO9XO46CFCALcgfIfaBJMb8pA9MsSHZn
TcWJUTDZcH33o5twzFu7g4Aiio1MIpZkIY0DI5y5R6PAy/GrANCwT5kEAQUId1Zn
B97Bwsz1s0Zwb3xLq/hpg1S0xNQWa22SuEVWAshhNBDAmAZ4fGJXM4Mwd45SxSTZ
kJZSVeTWnbv3SwB7xAmhTkd1hLpyXFKMPRFkV9U3yDEmDyNjIDJgp2UBLAagO8A3
h6UAPmb1TgnwZxC3YngZLqS7fm5LTI6nlkBDo5PzQ02jwI4qTsUoS00aif64ZVi5
w7EzdpimD86yGjm2Sotkr/+agiHnZn2Ag7CGbwiKRWZhX/f8ULByopb4p9CIMC6K
R4RzaHcZs5hMtG32fLQyR8bJohkBf1kLS4pGTfJmMprhZ2a0kEqmtbNxHQAUrJgg
GrxYLuBFGmqQc8IceEhIOuHzmC1ZV0gKPodHSKvIpACMlKKyjHpDa4x3A2PUvaST
yX7CDdXLULTgaYIcIPa0LnwBFp+ZEJICM296gP03fzvCsQQyKWzcz7unk7ikZzjl
e2WgZi80Q94miAKEgNYqJPsRxLG4piuqLN63RDlIQR7Ce8qmYlqcq2+WOgKqlbs5
NIYUr2U0YUC1njThAz6TduuYMbsMCiuxSyOSoWYWXGjCG44oeBNWsi23zIjFonog
LUDZZAkjyirkTVjrJt6SSWGbvzwHcN83rZSJvuaKoghJG+pbZMGJrj5oD9OIH9xG
IPUJfdI6jKI3e3HSXJi4hfZrCEczaClBmWKzEQmAskt7GuoQkA7TS7jaMOyWRvl1
gfX2EyQMOV3aD93KS3NpzevqCxgBb+50VpfxncFiejDqIP8KqH06m7VxS1yhxS4Y
DHQSVYdKDJikki+cgDXsNgv3TRy6TWt4hSIAx67zriD8GPPHRKXJbKzjEW/ljAbC
AkiBLrKpGsQBA7yUOV0wKRRISpKztraAMZO3VRhVmT/TWu2JNwnlIeDUJDd5cVfw
D7fxxoCDmCVRpxnRl1sDJQqWOViQOJPrDbxMYfCZSthrPIxMksX0f/pmdi2DRtRJ
pJ+RotHzrL9WSNR7iBOrQ28sRuDGaUKSL+s4Xz8GThwoYiG1Hk9RJCB2i06cgtoT
S/cQhXwhFEsqHM2lDyjAJfs7WxsWGLjmd+VzTK0nxfKrbxLoKclTRME7wHMCbT0k
nD/YRdw7KDD0xlQsxZ4LcokYMmm3jwIsnCMyt33iNYVUtNcQX577jN88JLLwpW93
jni3njAzFvUmYIwGRw6GDX5DGTJkrJOTvhEmROjgIXhVp1tJqk5bSAEhOPsCU0ZL
QsviHzGHtOaRAzJCu8f0G6lgPZlzrrfHvH+AqnjHfOdsCVKbah8LupyQtQPbR63i
dFcmWwZGXR6sukp3c0wDa5WoQ5jXupH46LXU1xPCMQcqd0TGlGh35r0aC4DfcVnW
j/n01DYg
-----END PUBLIC KEY-----
Alice's private key size: 64
Alice's public key size: ML-DSA-6x5
Message: Hello
Ciphertext (first 128 bytes out of 3309): 0360CA0970A6C332C866866774A4400588F48BC53A8418C14694A828636E0CDDCEF483E122ADDD24C35F4B8E17E068C6F7A0B6F2741BFD6DBE0408CC4E4E0428DC5CCEA3D1899F38CE01ECD904505DA3E8EE59622B6373FD9F4A488607EBFEE14E8536825BB2905EDD87EE11CD5EACBBBAE76787C489C2F19F785C2384AEA8D2
Alice's private key (PKCS#8 PEM):
-----BEGIN PRIVATE KEY-----
MDICAQAwCwYJYIZIAWUDBAMSBCAjhBEhK3EFjGftgD+WznMr8RxOMqd3cgggyfKM
2cl08g==
-----END PRIVATE KEY-----
```Alice 的公钥(SPKI PEM):
-----BEGIN PUBLIC KEY-----
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
YeBWbhWk
-----END PUBLIC KEY-----
验证(使用公钥):签名已验证
Alice 的公钥大小:1952
因此,PQC 迁移探索开始了。
更多 OpenSSL 的例子在这里:
https://asecuritysite.com/openssl
以及 Botan3:
https://asecuritysite.com/botan3/
- 原文链接: billatnapier.medium.com/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!