1
1
#if NET
2
+ using System ;
2
3
using System . Security . Cryptography ;
3
4
4
5
namespace Renci . SshNet . Security
@@ -22,26 +23,45 @@ public override byte[] GenerateClientPublicKey()
22
23
23
24
var q = _clientECDH . PublicKey . ExportParameters ( ) . Q ;
24
25
25
- return q . X ;
26
+ return EncodeECPoint ( q ) ;
26
27
}
27
28
28
29
public override byte [ ] CalculateAgreement ( byte [ ] serverPublicKey )
29
30
{
31
+ var q = DecodeECPoint ( serverPublicKey ) ;
32
+
30
33
var parameters = new ECParameters
31
34
{
32
35
Curve = _curve ,
33
- Q = new ECPoint
34
- {
35
- X = serverPublicKey ,
36
- Y = new byte [ serverPublicKey . Length ]
37
- } ,
36
+ Q = q ,
38
37
} ;
39
38
40
39
using var serverECDH = ECDiffieHellman . Create ( parameters ) ;
41
40
42
41
return _clientECDH . DeriveRawSecretAgreement ( serverECDH . PublicKey ) ;
43
42
}
44
43
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
+
45
65
protected override void Dispose ( bool disposing )
46
66
{
47
67
base . Dispose ( disposing ) ;
0 commit comments