11#if NET
2+ using System ;
23using System . Security . Cryptography ;
34
45namespace Renci . SshNet . Security
@@ -22,26 +23,45 @@ public override byte[] GenerateClientPublicKey()
2223
2324 var q = _clientECDH . PublicKey . ExportParameters ( ) . Q ;
2425
25- return q . X ;
26+ return EncodeECPoint ( q ) ;
2627 }
2728
2829 public override byte [ ] CalculateAgreement ( byte [ ] serverPublicKey )
2930 {
31+ var q = DecodeECPoint ( serverPublicKey ) ;
32+
3033 var parameters = new ECParameters
3134 {
3235 Curve = _curve ,
33- Q = new ECPoint
34- {
35- X = serverPublicKey ,
36- Y = new byte [ serverPublicKey . Length ]
37- } ,
36+ Q = q ,
3837 } ;
3938
4039 using var serverECDH = ECDiffieHellman . Create ( parameters ) ;
4140
4241 return _clientECDH . DeriveRawSecretAgreement ( serverECDH . PublicKey ) ;
4342 }
4443
44+ private static byte [ ] EncodeECPoint ( ECPoint point )
45+ {
46+ var q = new byte [ 1 + point . X . Length + point . Y . Length ] ;
47+ q [ 0 ] = 0x04 ;
48+ Buffer . BlockCopy ( point . X , 0 , q , 1 , point . X . Length ) ;
49+ Buffer . BlockCopy ( point . Y , 0 , q , point . X . Length + 1 , point . Y . Length ) ;
50+
51+ return q ;
52+ }
53+
54+ private static ECPoint DecodeECPoint ( byte [ ] q )
55+ {
56+ var cordSize = ( q . Length - 1 ) / 2 ;
57+ var x = new byte [ cordSize ] ;
58+ var y = new byte [ cordSize ] ;
59+ Buffer . BlockCopy ( q , 1 , x , 0 , x . Length ) ;
60+ Buffer . BlockCopy ( q , cordSize + 1 , y , 0 , y . Length ) ;
61+
62+ return new ECPoint { X = x , Y = y } ;
63+ }
64+
4565 protected override void Dispose ( bool disposing )
4666 {
4767 base . Dispose ( disposing ) ;
0 commit comments