Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

MLAPI.Cryptography - Easy cryptography for game networking

Discussion in 'Netcode for GameObjects' started by TwoTen, Jun 11, 2019.

  1. TwoTen

    TwoTen

    Joined:
    May 25, 2016
    Posts:
    1,168
    Doing cryptographic work in any languages with access to the .NET framework can be a breeze, in Unity's Mono version, not so much. It's missing critical things such as BigInt, ECDH-E and more. To address this, the MLAPI created it's own ECDH-E implementation a while back. I have now decided to break this out into it's own lib which is super easy to use.

    It's all open source, available on GitHub

    It has a BigInt and EllipticCurve implementation for the DIY folks, and a super easy API for the people that want easy cryptography.

    This includes a DiffieHellman implementation and a abstracted version that includes signed handshakes to prevent MITM attacks. Here is an example of how to use the signed version (The non signed is even easier to use, 3 lines per side, see the readme for instructions).

    Code (CSharp):
    1.  
    2. // Key pairs
    3. RSAParameters privateKey;
    4. RSAParameters publicKey;
    5.  
    6. // Generate keys, you can use X509Certificate2 instead of raw RSA keys.
    7. using (RSACryptoServiceProvider rsaGen = new RSACryptoServiceProvider(2048))
    8. {
    9.     privateKey = rsaGen.ExportParameters(true);
    10.     publicKey = rsaGen.ExportParameters(false);
    11. }
    12.  
    13. using (RSACryptoServiceProvider serverRSA = new RSACryptoServiceProvider())
    14. using (RSACryptoServiceProvider clientRSA = new RSACryptoServiceProvider())
    15. {
    16.     serverRSA.ImportParameters(privateKey);
    17.     clientRSA.ImportParameters(publicKey);
    18.  
    19.     // Both create their instances, constructor can take certificate instead or RSA key.
    20.     ECDiffieHellmanRSA serverDiffie = new ECDiffieHellmanRSA(serverRSA);
    21.     ECDiffieHellmanRSA clientDiffie = new ECDiffieHellmanRSA(clientRSA);
    22.  
    23.     // Exchange publics
    24.  
    25.     /* START TRANSMISSION */
    26.     byte[] serverPublic = serverDiffie.GetSecurePublicPart();
    27.     byte[] clientPublic = clientDiffie.GetSecurePublicPart();
    28.     /* END TRANSMISSION */
    29.  
    30.     // Calculate shared
    31.     byte[] key1 = serverDiffie.GetVerifiedSharedPart(clientPublic);
    32.     byte[] key2 = clientDiffie.GetVerifiedSharedPart(serverPublic);
    33. }
    34.  

    The above code, running both parts of the signed exchange with 2048 bit RSA keys takes ~70 milliseconds on my i7 7700k @4.2GHz, it's pretty fast.
     
    Last edited: Jun 12, 2019
    MadMojo and MurphyMurph_21 like this.
  2. maxhapeyenka

    maxhapeyenka

    Joined:
    Mar 12, 2023
    Posts:
    2
    Awesome, thanks!
    I see with this library client and server can come up with a shared key, but how can this key be used to encrypt data?

    Would be awesome to see Encrypt(string)/Decrypt(string) methods as well.
     
    Last edited: Dec 15, 2023