自研WebRTC客户端与GStreamer的DTLS握手失败排查求助
我正在开发自研WebRTC客户端作为业余项目,目前卡在DTLS实现环节,无法完成与GStreamer的P2P连接DTLS握手。
作为DTLS客户端发送Client Hello后,GStreamer返回了Server Hello、证书等消息;随后我发送了Flight 4消息(下图为抓包内容),但未收到GStreamer的Flight 5响应。

(已附Wireshark抓包与GStreamer日志)
怀疑问题出在发送的Flight 4消息中,但无法定位具体原因,已手动验证Premaster Secret、Master Secret、RSA、AES等所有计算过程的正确性。
使用的算法为TLS_RSA_WITH_AES_128_CBC_SHA,相关密钥信息如下:
- premaster secret :
FEFD9E38B76CF5780B6C58CBB55309C1C08EE1B5DF7D4507159115A8D459C35936FEEC2344698CF4A7F0689714C0BA19 - client random :
39623565396565382d333032332d343865642d383064392d6432346165616538 - server random :
a9dbe285e2ef980972812e45c86f6aaff1d486212bbb2d93744d2bae14813ae3
向服务器发送加密的Premaster Key
未加密的带填充Premaster Key:0225E7E44EF4694A39D4F4C458DC604DFBD806F2DB0FEF4136FC14FBC827541525900DACB6CEACE1679886270CEF2D9DEEEB05BB773A579B98718DD798DE2A1BE049C869201E9480C521691B25629D1D76C08BE92A7F99718720BBB2CC9BFA151E060BEFDF9BDDAC22B601557FC97E65A583D889A65A28EB2C22717AC2FEC6D82277D6F9E6FFD7F7A216EC4783E4F38E8C0EA393B4080D1FC73D8ED526EBC7466173563CC2B668E12104D85210246CE50A90D689238260FD7ACF9342DC4DDEC0BBDC7884FAB521DEE2DABF8DBAF300FEFD369DD3FE67938055892D6CF4C910C6A06F68524FAF557A087C22CEAAFD53038168EF713C58591157CD6F943FE6E
服务器公钥模数与指数:
- modulus:
8F207DA9E4D246C1C5D002C38C5983CDB0A8C86C8DDE6E7D2249BB1EC85F15CAEA4A0E4EC2EFEBF45A6CCCB1733E208D2852A986F458D60A14E386B6D35717B8C770957B9AD92ED44E19DA73F7626DA8E3329785137044AB8EE89D34F0A3BDE27E2E892BC78AAD904C038F6BCD1AAFA96E7808B0950423B0FDD26720EF2561F779C8309DDA5A6980823E0B1C03B3171E7C63997B606DB1E5BF64F6ABB72D2BBFCE1694CEA9B31D976163ECB3EDB4AB471D187C69FCAA0194A94F969DDD9BA2E59A1618FF1DCBC2C71062FF95DDD6CDEAEC0581D3FA685542DE68DA13E51B38EB8C74A69DADCD94287DC422ABF5FB7488E8122FC3FEC227BE0BA5A4A5874DA84D - exponent :
010001
加密后的Premaster Key:0194DF7D60F9992D633617A3D3E66F828D9D18ACEC75778808066A17A6F2625761901FF3C88970C588060358551F7B9F65DD6DC510525487C10A85FFCE33962C719113B18FF1D197CF96889E2A8348A0135939E139CEB5BCD6D9FF9D707604B455119AA97C4ADB1EBEF84101D7B1B9860241FF601DE4FDC79DB4901A1F43E71942E5044828D5106862B1FEDE79F1F928B05C55EDD796AD0F5BC6C56BC8386FA4F331B8292A4C5FEB9D98D087D2DC34AD1CF608FE40BDACAB8B679CEE40863E65E8687C90F73BB8C61530CD19CD58C63A1ABFAB7F2E9BA400210C22EB16F3BA57291EF53B2BC28B33B9817AB5CDE7559BB957470252B29E2434DBB264EB39117A
已使用服务器证书的模数与指数对上述消息加密,并在Key Exchange消息中发送。
从Premaster Secret推导Master Secret
Master Secret的PRF结果:991FE0D757F2E3422CB36B287974B8F1CFEA6EA464674D8CCCCA9111AF817BA0934F07F7F376B5ED1F507F7575A7CA03
用于推导密钥材料的密钥扩展结果:b2693e4352ac4a9669d92b4ba2a3153a9556b3ff82a347a85713bb4864e8d3cfbed57e8c60f6965cfc10b7c85a88934fa83fe883ee02f1a4fd6392045b87d38775c5e059f75613fefa3208b78d0b61f0245fcc6e10d68c56ab661da1641d132cb0a71ce0fd074cf6149826dbdd70bfc8d6139fccbdbe3182ad80bba13254339d
推导得到的密钥:
- AES CLIENT key :
88 04 d7 e0 41 c1 5a b4 3a f7 7f 40 d9 fd 0d 13 - AES CLIENT IV :
3a f3 3d 4c 30 57 14 6a 22 50 c7 56 97 c3 75 f7
使用上述密钥通过AES CBC加密Finish消息并发送。
已确认Certificate Verify消息正确,因为发送错误数据时GStreamer会返回签名错误。
带填充的未加密Finish消息:14 00 00 0c 00 00 00 00 00 00 00 0c ad f8 6f 17 16 a9 3f df 10 b9 c1 9b ca d1 f7 d2 21 58 97 26 72 08 15 bb d8 f0 61 81 49 4e 79 69 03 03 03 03
加密后的Finish消息(前16字节为客户端IV):3af33d4c3057146a2250c75697c375f710d8335f318be6ee18f3d49be4300e77bbb4aab65eb9caa35e983bad7101bf16920f46cb7822bc67b1801dbf0e0a1ea7
已通过在线工具解密验证,确认AES CBC加密正确(解密时需跳过前16字节IV):
更新
已通过Master Secret在Wireshark中解密DTLS数据包,查看日志后发现:
- Wireshark的密钥扩展结果与本地一致
- Finish消息解密正确且MAC验证通过
- 日志中无签名错误,说明Certificate Verify消息也正确
目前怀疑问题仅出在Client Key Exchange消息上,寻求帮助排查。
内容的提问来源于stack exchange,提问作者Usama

