使用AWS KMS和ML-DSA创建后量子签名指南

本文详细介绍了如何在AWS KMS中利用ML-DSA算法创建后量子安全签名,包括密钥生成、签名验证操作,以及处理大消息的外部mu预处理方法,帮助用户提前应对量子计算威胁。

如何使用AWS KMS和ML-DSA创建后量子签名

随着量子计算能力的发展,AWS致力于帮助客户领先应对公钥密码学面临的新兴威胁。今天,我们宣布将FIPS 204:基于模块格的数字签名标准(ML-DSA)集成到AWS密钥管理服务(AWS KMS)中。客户现在可以通过熟悉的AWS KMS API(包括CreateKey、Sign和Verify操作)创建和使用ML-DSA密钥进行数字签名。此新功能已全面推出,您可以在以下AWS区域使用ML-DSA:美国西部(北加利福尼亚)和欧洲(米兰),其余商业区域将在未来几天内跟进。此次发布是我们更广泛的AWS后量子密码学迁移计划的一部分,我们在最近的博客文章中已介绍过。在本文中,我们将指导您如何使用AWS KMS创建ML-DSA密钥和后量子签名。

许多组织使用AWS KMS对固件、操作系统、应用程序或其他工件进行加密签名。借助AWS KMS中的ML-DSA支持,您现在可以在FIPS-140-3第3级认证的HSM中生成和使用后量子密钥进行签名操作。通过现在实施ML-DSA签名,您可以帮助确保系统在整个运行寿命期间保持安全,即使密码学相关的量子计算机可用。这对于在生产过程中安装长期信任根(无论是直接嵌入硬件还是可能长期离线的设备中)的制造商尤其重要。在这两种情况下,加密签名在部署后不易更新,因此后量子准备对这些系统的整个运行寿命至关重要。

新增功能

AWS KMS提供三种新的AWS KMS密钥规范:ML_DSA_44、ML_DSA_65和ML_DSA_87,您可以将它们与新的后量子签名算法ML_DSA_SHAKE_256一起使用。与其他签名算法一样,此名称包括签名方案中用于在签名或验证之前消化消息的哈希函数。在这种情况下,使用的哈希函数是SHAKE256——NIST在FIPS 202中标准化的SHA-3哈希函数家族的一部分。

表1显示了每个密钥规范的详细信息,包括其NIST安全类别和相应的密钥大小(字节)。每个ML-DSA密钥规范代表了安全强度与资源需求之间的平衡。ML-DSA-44适用于需要与经典128位加密相当安全性的应用,而ML-DSA-65和ML_DSA_87分别提供逐步更强的安全级别,相当于经典192位和256位加密。随着安全级别的提高,您会注意到密钥和签名大小的相应增加,使您能够选择最符合安全需求和工程约束的密钥规范。

密钥规范 NIST安全级别(等效安全位) 公钥(字节) 私钥(字节) 签名(字节)
ML_DSA_44 1(128位) 1312 2560 2420
ML_DSA_65 3(192位) 1952 4032 3309
ML_DSA_87 5(256位) 2592 4896 4627

当使用带有RAW MessageType的AWS KMS Sign API时,要签名的消息限制为4096字节。对于大于4096字节的消息,需要在AWS KMS外部预处理消息以创建所谓的µ(mu),以生成较小尺寸的消息输入到KMS Sign API。此外部mu过程使用ML-DSA签名密钥对的公钥对消息进行预消化,创建64字节的消息大小。为了支持此发布,我们在KMS Sign API中添加了一个新的消息类型——EXTERNAL_MU——可用于ML-DSA签名或验证调用,以指示消息在提交到AWS KMS之前已使用µ(mu)进行预处理。

在以下部分中,我们包含有关构建外部mu的更多信息,并演示使用ML-DSA的基本AWS KMS操作。我们涵盖密钥创建、签名生成和验证,以及RAW和EXTERNAL_MU签名模式。请注意,当使用相同的消息和签名密钥时,生成的RAW或EXTERNAL_MU ML-DSA签名是相同的。

创建ML-DSA密钥

首先,使用AWS命令行界面(AWS CLI)示例命令创建一个非对称AWS KMS密钥:

1
aws kms create-key --key-spec ML_DSA_65 --key-usage SIGN_VERIFY

此命令将返回类似于以下的响应:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
    "KeyMetadata": {
        "Origin": "AWS_KMS",
        "KeyId": "1234abcd-12ab-34cd-56ef-1234567890ab",
        "MultiRegion": false,
        "Description": "",
        "KeyManager": "CUSTOMER",
        "Enabled": true,
        "SigningAlgorithms": [
            "ML_DSA_SHAKE_256"
        ],
        "CustomerMasterKeySpec": "ML_DSA_65",
        "KeyUsage": "SIGN_VERIFY",
        "KeySpec": "ML_DSA_65",
        "KeyState": "Enabled",
        "CreationDate": 1748371316.734,
        "Arn": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
        "AWSAccountId": "111122223333"
    }
}

记下响应中的KeyId或Arn值;您需要在后续签名操作中引用您的密钥。响应确认创建了一个配置为SIGN_VERIFY操作的ML_DSA_65密钥,该密钥将使用ML_DSA_SHAKE_256签名算法进行签名操作。

签名

在本节中,我们包含一些ML-DSA签名和验证JSON Web令牌(JWT)的示例,JWT通常用于在各方之间传输声明以进行Web授权。2021年,我们描述了如何使用椭圆曲线数字签名算法(ECDSA)(一种经典的非对称加密算法)签名和验证JWT(请参阅如何在解耦架构中大规模验证AWS KMS签名)。在以下示例中,令牌改为由AWS KMS管理的ML-DSA私钥签名,并在AWS KMS内部或使用OpenSSL外部验证。

要签名的JWT内容来自RFC7519的第3.1节。更具体地说,JWT头是:

1
2
{"typ":"JWT",
 "alg":"ML-DSA-65"}

JWT声明集是:

1
2
3
{"iss":"joe",
 "exp":1748952000,
 "http://example.com/is_root":true}

您可以通过使用头和有效负载的Base64URL编码来生成要签名的JWT消息:

1
2
3
4
echo -n -e '{"typ":"JWT",\015\012 "alg":"ML-DSA-65"}' | \
    basenc --base64url -w 0 | \
    sed 's/=//g' ; echo -n "." ; echo -n -e '{"iss":"joe",\015\012 "exp":1748952000,\015\012 "http://example.com/is_root":true}' | \
    basenc --base64url -w 0 | sed 's/=//g' ; echo ""

此命令将输出以下要用ML-DSA签名的Base64:

1
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ

请注意,以下示例以二进制格式输出由AWS KMS管理的ML-DSA私钥对消息生成的ML-DSA签名。您需要将它们转换为Base64URL以在JWT中使用,但各种数据加密和签名格式可以使用这些签名。这些包括加密消息语法(CMS)、CBOR对象签名和加密(COSE)或用于UEFI和Open Titan的图像签名编码。虽然在二进制和这些格式之间转换很简单,但在撰写本文时,这些签名格式的常见加密实现可能不支持新算法。

RAW ML-DSA签名(无外部mu)

要在AWS KMS中使用ML-DSA签名小于4096字节的消息,您可以使用AWS CLI:

1
2
3
4
5
6
7
aws kms sign \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message ' eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ' \
    --message-type RAW \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --output text \
    --query Signature | base64 --decode > ExampleSignature.bin

确保将目标密钥ID值<1234abcd-12ab-34cd-56ef-1234567890ab>替换为您的KeyId。此命令将生成一个签名并将其写入磁盘为ExampleSignature.bin。

生成签名后,您可以使用单个命令创建完整的JWT(包括头、有效负载和签名):

1
2
3
echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ." ; \
    basenc --base64url -w 0 ExampleSignature.bin | \
    sed 's/=//g' ; echo ""

此命令将输出符合RFC 7519要求并使用AWS KMS签名的即用型JWT:

1
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.<base64url of the signature as per RFC7519>

外部mu ML-DSA签名

请注意,AWS KMS在使用Sign API时对原始消息的大小施加4096字节的限制,以最小化响应延迟。在要签名的消息大于4096字节或如果预消化外部mu具有您需要的性能优势的情况下,您必须在AWS KMS中使用EXTERNAL_MU消息类型而不是RAW。

在使用带有AWS KMS Sign API的EXTERNAL_MU消息类型之前,您必须在本地对消息执行预哈希计算。因此,首先从AWS KMS检索公钥,并使用以下命令将其转换为DER格式(将示例密钥ID替换为您的AWS账户中的有效密钥ID):

1
2
3
4
aws kms get-public-key \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --output text \
    --query PublicKey | base64 --decode > public_key.der

构建外部mu摘要:

  1. 构造消息前缀(M):M =(域分隔符 || 上下文长度 || 上下文 || 消息)。在此示例中,将域分隔符值和上下文长度设置为零;这将签名中使用的上下文设置为空字符串,这是默认值。
  2. 哈希公钥然后将其预置到消息前缀:(SHAKE256(pk) || M’)。
  3. 哈希以产生64字节的mu:Mu = SHAKE256(SHAKE256(pk) || M’)

您可以使用单个OpenSSL 3.5命令构建摘要:

1
2
3
4
5
6
{
    openssl asn1parse -inform DER -in public_key.der -strparse 17 -noout -out - 2>/dev/null |
    openssl dgst -provider default -shake256 -xoflen 64 -binary;
    printf '\x00\x00';
    echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
} | openssl dgst -provider default -shake256 -xoflen 64 -binary > mu.bin

现在您可以调用AWS KMS对64字节摘要进行签名以在文件ExampleSignature.bin中生成ML-DSA签名,确保将MessageType设置为EXTERNAL_MU:

1
2
3
4
5
6
7
aws kms sign \
    --key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
    --message fileb://mu.bin \
    --message-type EXTERNAL_MU \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --output text \
    --query Signature | base64 --decode > ExampleSignature.bin

最终签名的JWT令牌与之前在RAW模式下生成的相同。

使用AWS KMS进行签名验证

在本节中,我们向您展示如何使用AWS KMS或在您自己的环境中本地验证ML-DSA签名。我们假设您在ExampleSignature.bin中有一个ML-DSA签名,该签名是在JWT内容上使用AWS KMS中的私钥生成的,并由KEY_ARN标识。

请注意,尽管以下示例演示了使用直接从AWS KMS获取的公钥进行签名验证,但这些相同的原则扩展到基于证书的系统,例如私有PKI,其中公钥嵌入在最终实体证书(签名者)中。在这种情况下,验证者首先通过验证证书链与受信任根的关联来验证签名者的身份,然后使用最终实体证书的公钥来验证内容的ML-DSA签名。IETF正在通过RFC草案draft-ietf-lamps-dilithium-certificates标准化ML-DSA在X.509证书中的使用。

RAW ML-DSA验证

要使用AWS KMS验证签名,您可以调用以下命令,将示例密钥ID替换为您用于签名的相同密钥ID。

1
2
3
4
5
6
aws kms verify \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ" \
    --message-type RAW \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --signature fileb://ExampleSignature.bin

响应将返回:

1
2
3
4
5
{
    "KeyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
    "SignatureValid": true,
    "SigningAlgorithm": "ML_DSA_SHAKE_256"
}

验证结果存储在SignatureValid字段中。

外部mu ML-DSA验证

如果您在mu.bin中有JWT内容的外部mu摘要以及签名和AWS KMS中相应的密钥对,您可以使用摘要而无需访问整个消息或重新计算摘要。

1
2
3
4
5
6
aws kms verify \
    --key-id <1234abcd-12ab-34cd-56ef-1234567890ab> \
    --message fileb://mu.bin \
    --message-type EXTERNAL_MU \
    --signing-algorithm ML_DSA_SHAKE_256 \
    --signature fileb://ExampleSignature.bin

要从消息和公钥重新生成外部mu mu.bin,请参阅上面的外部mu ML-DSA签名部分。

使用OpenSSL 3.5进行本地签名验证

如果您想减少AWS KMS API消耗成本并更好地控制API配额的使用,同时保持AWS KMS生成和存储的ML-DSA签名生成密钥的安全性,您可以在AWS KMS之外本地验证ML-DSA签名。

在此示例中,您使用OpenSSL 3.5验证ExampleSignature.bin中的签名。您首先必须从AWS KMS获取DER编码的公钥,如外部mu ML-DSA签名部分所示,存储在文件public_key.der中。然后,OpenSSL 3.5可以使用公钥验证消息上的签名。

1
2
echo -n "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJNTC1EU0EtNjUifQ.eyJpc3MiOiJqb2UiLA0KICJleHAiOjE3NDg5NTIwMDAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ" | \
    openssl dgst -verify public_key.der -signature ExampleSignature.bin

成功验证将输出:Verified OK

结论

今天在AWS KMS中推出ML-DSA支持标志着我们在后量子密码学承诺中的重要里程碑。通过三种不同安全级别的ML-DSA,包括原始和外部摘要模式,您有灵活的选择来满足安全需求,同时为量子计算时代做准备。与现有AWS KMS API的无缝集成使您今天就可以轻松地将抗量子签名纳入您的应用程序。如果您需要以下内容,此实现尤其有价值:

  • 在使用后量子密码学时满足FIPS 140-3合规要求。
  • 签名代码、工件、文档或其他需要在未来许多年(包括密码学相关量子计算机存在后的时期)保持可信和可验证的数据。
  • 使用先前已批准使用的加密服务
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计