我正在尝试使用.net在TLS 1.2上进行ECDHE密钥交换。服务器正在响应server_key_exchange消息,该消息以04开头,所以我猜它是未加密的。根据我的理解,消息的前32位被视为值X,接下来的32位被视为值Y.使用这些和椭圆曲线(例如secp256r1),创建服务器的公钥值。我指的是来自OpenTLS的以下python代码:
class ECDHE_RSA_Key_Exchange:
def __init__(self, server_key_exchange):
curve_code = bytes_to_hex(server_key_exchange[5:7])
print('Elliptic curve: ' + elliptic_curves[curve_code])
self.curve = reg.get_curve(elliptic_curves[curve_code])
x = bytes_to_int(server_key_exchange[9:9+32])
y = bytes_to_int(server_key_exchange[9+32:9+64])
self.server_pubKey = ec.Point(self.curve, x, y)
正在考虑使用C#资源来实现相同目标。以下是我可以做的一些移植:
int skeLen = this.sKeyExch_hs[7];
skeLen = skeLen - 1;
byte[] sPubKey = new byte[skeLen];
Buffer.BlockCopy(this.sKeyExch_hs, 9, sPubKey, 0, skeLen);
ECDiffieHellmanCng ecdhCngClient = new ECDiffieHellmanCng(256);
this.client_pub_key = ecdhCngClient.PublicKey.ToByteArray();
byte[] i = {0x04};
this.client_pub_key = this.client_pub_key.Skip(8).ToArray();
this.client_pub_key = i.Concat(this.client_pub_key).ToArray();
byte[] x = {0x45, 0x43, 0x4B, 0x31, 0x20, 0, 0, 0};
sPubKey = x.Concat(sPubKey).ToArray();
ECDiffieHellmanPublicKey serverKey = ECDiffieHellmanCngPublicKey.FromByteArray(sPubKey, CngKeyBlobFormat.EccPublicBlob);
byte[] symmKey = ecdhCngClient.DeriveKeyMaterial(serverKey);
this.pre_master_secret = symmKey;
this.pre_master_secret_list = new List<byte>(this.pre_master_secret);
byte client_pub_key_len = (byte) this.client_pub_key.Length;
this.ckeMessage = new List<byte>();
this.ckeMessage.Add(client_pub_key_len);
this.ckeMessage.AddRange(this.client_pub_key);
return this.ckeMessage;