Curve25519 KEX is now based on BouncyCastle instead of Chaos.NaCl (#1447)

* Curve25519 KEX is now based on BouncyCastle instead of Chaos.NaCl

* Abstract SecureRandom

---------

Co-authored-by: Wojciech Nagórski <wojtpl2@gmail.com>
This commit is contained in:
Scott Xu
2024-07-24 03:40:09 +08:00
committed by GitHub
parent 4cc1278d7c
commit 71e2909dec
3 changed files with 26 additions and 15 deletions
@@ -1,11 +1,16 @@
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Prng;
using Org.BouncyCastle.Security;
namespace Renci.SshNet.Abstractions
{
internal static class CryptoAbstraction
{
private static readonly RandomNumberGenerator Randomizer = RandomNumberGenerator.Create();
internal static readonly SecureRandom SecureRandom = new SecureRandom(new CryptoApiRandomGenerator(Randomizer));
/// <summary>
/// Generates a <see cref="byte"/> array of the specified length, and fills it with a
/// cryptographically strong random sequence of values.
@@ -1,14 +1,18 @@
using Renci.SshNet.Abstractions;
using System;
using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
using Renci.SshNet.Security.Chaos.NaCl;
using Renci.SshNet.Security.Chaos.NaCl.Internal.Ed25519Ref10;
namespace Renci.SshNet.Security
{
internal sealed class KeyExchangeECCurve25519 : KeyExchangeEC
{
private byte[] _privateKey;
private X25519Agreement _keyAgreement;
/// <summary>
/// Gets algorithm name.
@@ -38,13 +42,13 @@ namespace Renci.SshNet.Security
Session.KeyExchangeEcdhReplyMessageReceived += Session_KeyExchangeEcdhReplyMessageReceived;
var basepoint = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
basepoint[0] = 9;
var g = new X25519KeyPairGenerator();
g.Init(new X25519KeyGenerationParameters(CryptoAbstraction.SecureRandom));
_privateKey = CryptoAbstraction.GenerateRandom(MontgomeryCurve25519.PrivateKeySizeInBytes);
_clientExchangeValue = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
MontgomeryOperations.scalarmult(_clientExchangeValue, 0, _privateKey, 0, basepoint, 0);
var aKeyPair = g.GenerateKeyPair();
_keyAgreement = new X25519Agreement();
_keyAgreement.Init(aKeyPair.Private);
_clientExchangeValue = ((X25519PublicKeyParameters)aKeyPair.Public).GetEncoded();
SendMessage(new KeyExchangeEcdhInitMessage(_clientExchangeValue));
}
@@ -96,9 +100,11 @@ namespace Renci.SshNet.Security
_hostKey = hostKey;
_signature = signature;
var sharedKey = new byte[MontgomeryCurve25519.PublicKeySizeInBytes];
MontgomeryOperations.scalarmult(sharedKey, 0, _privateKey, 0, serverExchangeValue, 0);
SharedKey = sharedKey.ToBigInteger2().ToByteArray().Reverse();
var publicKey = new X25519PublicKeyParameters(serverExchangeValue);
var k1 = new byte[_keyAgreement.AgreementSize];
_keyAgreement.CalculateAgreement(publicKey, k1, 0);
SharedKey = k1.ToBigInteger2().ToByteArray().Reverse();
}
}
}
+2 -2
View File
@@ -5,8 +5,8 @@ using Org.BouncyCastle.Crypto.Agreement;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Security;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
@@ -41,7 +41,7 @@ namespace Renci.SshNet.Security
CurveParameter.GetSeed());
var g = new ECKeyPairGenerator();
g.Init(new ECKeyGenerationParameters(_domainParameters, new SecureRandom()));
g.Init(new ECKeyGenerationParameters(_domainParameters, CryptoAbstraction.SecureRandom));
var aKeyPair = g.GenerateKeyPair();
_keyAgreement = new ECDHCBasicAgreement();