如果我用我的私钥签署一条非常短的消息(0 或 1)(并且接收方使用公钥验证签名),这是否比发送足够长的签名消息更不安全?
我可以使用 RSA 私钥签署单字符消息吗?
问题不在于伪造签名,而在于消息的含义。
签名的不是消息,而是消息的哈希。哈希总是相同的长度。
可以对由单个位或字节组成的消息进行哈希处理,因此可以对其进行签名,因此可以证明您的密钥对其进行了签名。
但即使可以证明,那信息又是什么意思呢?如果它是“是/否”问题的答案,您仍需要包含对正在回答的问题的一些参考,以防止重放攻击。
- 爱丽丝:你的名字是h22吗?
- 鲍勃:(
Signed(Yes)
夏娃偷听) - 爱丽丝:你犯了颠覆活动吗?
- 夏娃:(
Signed(Yes)
爱丽丝认为这是鲍勃的)
因此,每个答案都需要包含对问题的某种引用,因此不能重复使用答案。您可以通过为每个问题提供一个“仅使用一次的数字”(随机数)来做到这一点,并将其包含在回复中。
- 爱丽丝: Q1:你的名字是h22吗?
- 鲍勃:(
Signed(Q1:Yes)
夏娃偷听) - 爱丽丝: Q2:你犯了颠覆活动吗?
- Eve:(
Signed(Q1:Yes)
爱丽丝没有被骗——这是错误的问题编号,所以是重放攻击) - 鲍勃:(
Signed(Q2:No)
爱丽丝现在知道这真的是鲍勃)
当然,爱丽丝也确实需要在她的问题上签名。否则,马洛里可能会欺骗鲍勃回答不同的问题。
- 爱丽丝: Q1:你的名字是h22吗?
- 鲍勃:
Signed(Q1:Yes)
- 爱丽丝: Q2:你犯了颠覆活动吗?(被马洛里拦截)
- 马洛里: Q2:你被称为 h 吗?
- Bob:(
Signed(Q2:Yes)
回答 Mallory 的问题,但 Alice 认为这是对她的回答)。
因此,保护整个对话非常重要。实际上,这通常意味着包括时间和日期作为签名消息的一部分,以及双向签名消息,并使用随机数防止重播。
如果我使用我的私钥给未加密的消息 M 签名并给出签名 S,那么世界上的任何人都可以阅读该消息,并且会知道用我的私钥签名的消息 M 给出了签名 S。如果您期望我的回复,那么世界上的任何人都可以给你带有签名 S 的响应 M,你会知道它是用我的私钥签名的,除了这个消息不是给你的。
因此,如果我曾经用我的私钥同时签署了消息“是”和消息“否”,并且你问“你是否同意我们的计划”,那么任何人都可以发送消息“是”或消息“否”给你,显然是我签名的。
为了避免这种风险,您可以生成一个长随机数 R 并告诉我“您是否同意我们的计划,请在您的回复中包含 R”。然后,您将只接受回复“Yes R”和“No R”。由于 R 是随机的,我之前从未发送并签名过“Yes R”或“No R”,所以没有人可以伪造它。
数字签名算法适用于任意长度的位序列的输入。实际上,大多数工作是首先对要签名(或验证)的数据进行哈希处理,然后仅对哈希函数输出进行操作;因此,消息可以是任何适合散列函数的内容。因此,一个字节的消息,甚至是一个空的消息,当然可以被处理。
(大多数散列函数都有一个正式的最大输入长度,但通常如此荒谬,以至于实际上它与无限一样好。例如,SHA-256 接受高达 2 64 -1 位的输入,超过几百万兆兆字节。)
现在,当然,数字签名仅证明私钥在某个时候涉及特定输入消息;它所传达的含义并不比您选择放入消息中的内容更多,而且单字节消息中没有太多空间。@Ben 在他的回答中展示了攻击者如何脱离上下文重用已签名的消息;这通常被称为重放攻击,通常的对策是使用随机数:输入包括一个由要验证签名的人提供的值,并且验证者确保它只会接受给定的随机数一次. 在 8 位消息中,您最多可以容纳 256 个不同的 nonce 值,因此这很快就会变得非常有限。
让消息脱离上下文不仅不安全,还可能导致私钥泄露:http ://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-危急/
因此签名操作通常在 hash(random padding + hash(message)) 上执行,而不仅仅是 (message) 或 hash(message)。见https://www.rfc-editor.org/rfc/rfc3447#section-9.1.1
类似的东西也适用于加密。鉴于在 PK 系统中通常任何人都可以加密消息,因此对同一消息的每次加密都会产生不同的结果。否则就有可能产生一个包含所有短消息密文的字典。
如果您的对手只交换两种短消息“aiourghaoihvbu”和“048yqnb038”,您可能可以在不进行任何加密的情况下计算出哪个意味着是,哪个意味着不是。