Search code examples
c#keyrsaencryption-asymmetricrobust

C# robust key pair match


I'm generating a key pair in this way

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

If we do a simple Console.Write(_publicKey) we have

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

If we do a simple 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>

I want to check if the two keys, once generated and saved, are matching.

As we know anyone has access to the public key.

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

For what I read, to check if a private and public key are of the same pair we verify that the Modulus is the same and that Exponent of the public key is equal to PublicExponent of the private key

If I take the public key and I do:

    <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>

As you can see, if I consider only the modulus and exponent, this private key match the public key (!).

Considering that a text is encrypted with the public key, and decrypted with the private key, is clear that no one can decrypt a message with this forged key. So, a forged key like this, is useless.

I'm just wondering, if there is something else to do for a robust key pair match.


Solution

  • @JamesKPolk Imagine a scenario where the server contains all the public keys.

    To check if the two keys are matching, the server use the public key of a user to encrypt the hash of a phrase chosen randomly

    The server send the encrypted hash to the client

    The client decrypt the hash with his private key

    The client send the decrypted hash to the server

    If the hash is the same of the one used initially, and we repeat the proof multiple times, we have a key match.

    On client side I can also check the consistency of the private key, in the way you suggested.