This API handles the required handshake payloads and encryption/decryption for Samsung J series smart TVs
The API is designed in ASP .NET CORE 3.1 which also inclues an API Documentation called SWAGGER which can be accessed under http://{IpOfAPI}:{PortOfAPI}/swagger.
In SWAGGER all API Endpoints are listed with their StatusCodes and ResponseTypes. They also could be tested from there, but you will get an 401 Unauthorized because we cannot set headers there (see authentication)
The API is protected via a simple GUID which is configured in the appsettings.json which is only accessible on the server. To use that Authentication you always need to inlcude the Header X-Api-Guid : {GUID}.
The configuration looks like this:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ApiGuid": "1234"
}
To do a successfull handshake a couple of HTTP requests are required to get a valid encryption key and a session id. The API only provides the payloads that are send to the TV.
All values in the {} must be replaced by the actual values.
-
request a pin page on the TV with
http://{IpOfTv}:8080/ws/apps/CloudPINPage -
post that pin (as body and header
Content-Type : application/json) tohttp://{IpOfAPI}:{PortOfAPI}/pairing?pairingId={UniqeIdForSession}&resource=ServerHello -
the reponse is like:
{ "data": "010200000000000000008A00000006363534333231...(truncated)" } -
wrap the
DATAinto:{ "auth_data": { "auth_type" : "SPC", "GeneratorServerHello" : "{DATA}" } } -
POST the wrapped data to:
http://{IpOfTv}:8080/ws/pairing?step=1&app_id=com.samsung.companion&device_id={SameIdOfYourChoice}&type=1 -
the response is like:
{ "auth_data":" { "auth_type" : "SPC", "request_id" : "0", "GeneratorClientHello" : "010100000000000000009E00000006363534333231040C1D...(truncated)" } } -
get the
GeneratorClientHelloand theRequestIdwith regex:[{\"\w:]GeneratorClientHello[\\\":]*([\d\w]*)and[{\"\w:]request_id[\\\":]*([\d\w]*) -
send the
GeneratorClientHelloto:http://{IpOfApi}:{PortOfApi}/pairing?pairingId={UniqeIdForSession}&resource=ClientHellothis will internally validate against the previous data (true or false)
-
send a POST request (without any body) to:
http://{IpOfApi}:{PortOfApi}/pairing?pairingId={UniqeIdForSession}&resource=ServerAck -
the reponse is like:
{ "data" : "01030000000000000000144D4ECE8F61EACE69A95C38D028B...(truncated)" } -
wrap the
DATAin:{ "auth_data": { "auth_type" : "SPC", "request_id" : "{RequestId}", "ServerAckMsg" : "{DATA}" } } -
POST the wrapped data to:
http://{IpOfTv}:8080/ws/pairing?step=2&app_id=com.samsung.companion&device_id={SameIdOfYourChoice}&type=1 -
the response is like:
{ "auth_data":" { "auth_type" : "SPC", "request_id" : "0", "ClientAckMsg" : "0104000000000000000014BEC4282F6456E06F7090...{truncated}", "session_id" : "21" } } -
grab the
ClientAckMsgwith[{\"\w:]ClientAckMsg[\\\":]*([\d\w]*)and theSessionIdwith[{\"\w:]session_id[\\\":]*([\d\w]*) -
send the
ClientAckMsg(as body with headerContent-Type : application/json) to:http://{IpOfApi}:{PortOfApi}/pairing?pairingId={UniqeIdForSession}&resource=ClientAckthis will internally validate against the previous data (true or false)
-
send a POST request (without any body) to:
http://{IpOfApi}:{PortOfApi}/pairing?pairingId={UniqeIdForSession}&resource=Session -
the response is like:
{ "Key" : "SgJSLL5L0Pjh34...(truncated)" } -
close the pin page on TV with DELETE request to:
http://{IpOfTv}:8080/ws/apps/CloudPINPage/run
Save the SessionId and the Key for later.
Now you're successfully paired to the TV. You can use the same PIN to always request a EncryptionKey just start at step 2. so the same process without showing a PIN page on TV ;-)
From now you can use that KEY and the SessionId to encrypt/decrypt the required messages which are end trough the websocket connection, OR use the encryption/decryption endpoints from the API which uses the created KEYand SessionId automatically.