C# 健壮的密钥对匹配

C# robust key pair match

我正在以这种方式生成密钥对

var rsa = new RSACryptoServiceProvider();
_privateKey = rsa.ToXmlString(true);
_publicKey = rsa.ToXmlString(false);

如果我们做一个简单的 Console.Write(_publicKey) 我们有

    <RSAKeyValue>
      <Modulus>nW/DERb839Z6fM594Eg3Y3AnpEKjMP/QzGn/iJW9snGkIl3crsa6a+g8S7uKNM0rBNoIdYnMlJTRDoPBpl35eO+ad/V0K9CJ+AqAo4q2pVEsJJujjhNX0C6wwrocS5vGWnuX02JZzVwiQxailo0qdq0qYLhp2ckQLUfwGxWr1mU=</Modulus>
      <Exponent>AQAB</Exponent>
    </RSAKeyValue>

如果我们做一个简单的 Console.Write(_privateKey)

    <RSAKeyValue>
      <Modulus>nW/DERb839Z6fM594Eg3Y3AnpEKjMP/QzGn/iJW9snGkIl3crsa6a+g8S7uKNM0rBNoIdYnMlJTRDoPBpl35eO+ad/V0K9CJ+AqAo4q2pVEsJJujjhNX0C6wwrocS5vGWnuX02JZzVwiQxailo0qdq0qYLhp2ckQLUfwGxWr1mU=</Modulus>
      <Exponent>AQAB</Exponent>
      <P>wrI5ll8sm45OI+jGNVombQB9YUMMzlHgiP//q8N6shYDkmaGrijYrM0/xm9mXn8sxTvg+jX55159Mpuk1rIiBw==</P>
      <Q>zwIriOVyG45A3i3UHQt+KijTz1kSw+m03Fbw3WDbh2ooYewCvLoLFWCsgk1TeXfMK5u7dLdttgGqC27qd6i5Mw==</Q>
      <DP>JL4dwBMWCAVDGePEBC2PMuL0xnYw5H7vMOufBHtPnGwrIGXY5OUwfuv9LSW42/yEJnS2cIHfN5rNZc+ZvCrB4Q==</DP>
      <DQ>aL53WtCGeWz0Y7easYukLh70deFjPmBd1HPlco7U5eMQReQOyoH0o7+D6nbH+xlj5Njq9DbwO30CFsDrwNpNww==</DQ>
      <InverseQ>OV9TPLS5fli7K59hGH1m5ZnTT80UY9XJzKRFRjWuDHI1P7QL+d6+1d08DAICDWTu6ac/1jD8ibmO6AxOmYw6OQ==</InverseQ>
      <D>kiQjm+KN2645R09as2311F1Qvv6Ig7yDcqzWYlA1pcYtiSU97BNXC0GpbtdohHkK/Nbz0T+X4zh9Ew8lHCzRnIdSQZwGyeCXmk8QNvzK3HTOmLgaTu6UaNFtilqgYWzXHuu8WtvWyyN5F3bLb+PYJ1hAMCrS1RxOqlxXczgSqQU=</D>
    </RSAKeyValue>

我想检查生成并保存后的两个密钥是否匹配。

据我们所知,任何人都可以访问 public 密钥。

ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf

根据我的阅读,为了检查私钥和 public 密钥是否属于同一对,我们验证模数是否相同并且 public 密钥的指数等于 PublicExponent私钥

如果我按下 public 键,我会:

    <RSAKeyValue>
      <Modulus>nW/DERb839Z6fM594Eg3Y3AnpEKjMP/QzGn/iJW9snGkIl3crsa6a+g8S7uKNM0rBNoIdYnMlJTRDoPBpl35eO+ad/V0K9CJ+AqAo4q2pVEsJJujjhNX0C6wwrocS5vGWnuX02JZzVwiQxailo0qdq0qYLhp2ckQLUfwGxWr1mU=</Modulus>
      <Exponent>AQAB</Exponent>
      <P>Hi-guys==</P>
      <Q>Im-doing-something-nasty==</Q>
      <DP>to-pass==</DP>
      <DQ>the-key-check==</DQ>
      <InverseQ>XXXXXXXXXXXXXXXX==</InverseQ>
      <D>YYYYYYYYYYYYYYYYYYYYYYYYY=</D>
    </RSAKeyValue>

如您所见,如果我只考虑模数和指数,则此私钥与 public 密钥匹配 (!)。

考虑到文本是用 public 密钥加密的,并用私钥解密的,很明显没有人可以用这个伪造的密钥解密消息。所以,像这样的伪造密钥是没有用的。

我只是想知道,是否还有其他方法可以实现可靠的密钥对匹配。

@JamesKPolk 想象一下服务器包含所有 public 键的场景。

为了检查两个密钥是否匹配,服务器使用用户的 public 密钥来加密随机选择的短语的哈希值

服务器将加密后的散列值发送给客户端

客户端用自己的私钥解密hash

客户端将解密后的哈希发送给服务器

如果哈希值与最初使用的哈希值相同,并且我们多次重复证明,则我们有一个密钥匹配。

在客户端,我也可以按照您建议的方式检查私钥的一致性。