This report summarizes the relevant request and response flow from:
docs/line-letter-sealing-off.jsondocs/line-letter-sealing-on-to-off.json
The source files are Chrome net-export captures, not HAR files.
- Chrome net-export preserves request headers, response headers, response bodies, and upload sizes.
- The request body is not exposed at the high-level
URL_REQUEST/UPLOAD_DATA_STREAM_*layer in a directly usable form. - The request body is recoverable at a lower layer by correlating
HTTP2_SESSION_SEND_HEADERSwithSSL_SOCKET_BYTES_SENTHTTP/2 DATA frames. - This report now uses those recovered request bodies where available.
- Some request fields are still application-level encrypted blobs even after extraction, most notably
loginV2.password. - Secrets are redacted in this report:
- access tokens
- cookies
- HMACs
- verifier values
- QR auth session IDs
Most requests in both traces share these headers:
:authority: line-chrome-gw.line-apps.com
:scheme: https
accept: application/json, text/plain, */*
accept-language: en-US
content-type: application/json
origin: chrome-extension://ophjlpahpchlmihnnnihgmmeilfjmjjc
user-agent: Mozilla/5.0 (...) Chrome/146.0.0.0 Safari/537.36
x-lal: en_US
x-line-chrome-version: 3.7.2
x-hmac: <redacted>Special cases:
- QR poll and permit-notice requests add
x-line-session-idandx-lst. - Authenticated Talk requests add:
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>This capture is mostly a login flow for a Letter Sealing off account, followed by logout. It also contains two incidental post-login group text sends before logout.
Request:
POST /api/talk/thrift/Talk/AuthService/loginV2
content-length: 549Request payload:
[
{
"type": 2,
"identityProvider": 1,
"identifier": "15327",
"password": "<app-encrypted blob>",
"keepLoggedIn": false,
"accessLocation": "",
"systemName": "Chrome",
"certificate": "",
"verifier": "",
"secret": "<secret>",
"e2eeVersion": 1,
"modelName": ""
}
]Response:
{
"code": 10051,
"message": "RESPONSE_ERROR",
"data": {
"name": "TalkException",
"message": "TalkException",
"code": 89,
"reason": "not supported",
"parameterMap": null
}
}Request:
POST /api/talk/thrift/Talk/AuthService/loginV2
content-length: 505Request payload:
[
{
"type": 0,
"identityProvider": 1,
"identifier": "15343",
"password": "<app-encrypted blob>",
"keepLoggedIn": false,
"accessLocation": "",
"systemName": "Chrome",
"certificate": "",
"verifier": "",
"secret": "",
"e2eeVersion": 1,
"modelName": ""
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"verifier": "<redacted verifier>",
"pinCode": "2423",
"type": 3,
"lastPrimaryBindTime": "0"
}
}Request:
GET /api/talk/long-polling/JQ
x-line-session-id: <redacted verifier>
x-lst: 180000Response:
{
"code": 0,
"message": "OK",
"data": {
"result": {
"verifier": "<redacted verifier>",
"authPhase": "QRCODE_VERIFIED",
"userAuthLogEventListNotValid": true
},
"timestamp": "1773625290467"
}
}Request:
POST /api/talk/thrift/Talk/AuthService/loginV2
content-length: 232Request payload:
[
{
"type": 1,
"identityProvider": 1,
"identifier": "",
"password": "",
"keepLoggedIn": false,
"accessLocation": "",
"systemName": "Chrome",
"certificate": "",
"verifier": "<redacted verifier>",
"secret": "",
"e2eeVersion": 1,
"modelName": ""
}
]Response headers of note:
set-cookie: lct=<redacted jwt>; path=/; samesite=none; secure; httponlyResponse body shape:
{
"code": 0,
"message": "OK",
"data": {
"certificate": "<redacted certificate>",
"type": 1,
"lastPrimaryBindTime": "1483535856056",
"tokenV3IssueResult": {
"accessToken": "<redacted jwt>",
"refreshToken": "<redacted refresh token>",
"durationUntilRefreshInSec": "...",
"loginSessionId": "...",
"tokenIssueTimeEpochSec": "..."
},
"mid": "<logged-in user MID>"
}
}These are not part of the login itself, but they are in the file.
Request 1:
POST /api/talk/thrift/Talk/TalkService/sendMessage
content-length: 272
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
662642008,
{
"from": "<logged-in user MID>",
"to": "<group MID>",
"toType": 2,
"id": "local-662642008",
"createdTime": "1773625306000",
"sessionId": 0,
"text": "テスト",
"contentType": 0,
"contentMetadata": {},
"hasContent": false
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"from": "<logged-in user MID>",
"toType": 2,
"id": "605311889450205372",
"createdTime": "1773625305497",
"deliveredTime": "0",
"hasContent": false,
"contentType": 0,
"sessionId": 0,
"reactions": []
}
}Request 2:
POST /api/talk/thrift/Talk/TalkService/sendMessage
content-length: 272
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
662642009,
{
"from": "<logged-in user MID>",
"to": "<second group MID>",
"toType": 2,
"id": "local-662642009",
"createdTime": "1773625310000",
"sessionId": 0,
"text": "テスト",
"contentType": 0,
"contentMetadata": {},
"hasContent": false
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"from": "<logged-in user MID>",
"toType": 2,
"id": "605311896362418782",
"createdTime": "1773625309725",
"deliveredTime": "0",
"hasContent": false,
"contentType": 0,
"sessionId": 0,
"reactions": []
}
}Important note:
sendMessageresponses do not include the message text.- The actual text appears in the
/api/operation/receiveevent stream.
Request:
POST /api/talk/thrift/Talk/AuthService/logoutV2
content-length: 2
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[]Response:
{
"code": 0,
"message": "OK"
}Response headers of note:
set-cookie: lct=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT; samesite=none; secure; httponlyObserved requests:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginService/createSession
content-length: 4Request payload:
[{}]Response:
{
"code": 0,
"message": "OK",
"data": {
"authSessionId": "<redacted auth session id>"
}
}Then:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginService/createQrCode
content-length: 88Request payload:
[
{
"authSessionId": "<redacted auth session id>"
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"callbackUrl": "https://line.me/R/au/lgn/sq/<redacted auth session id>",
"longPollingMaxCount": 2,
"longPollingIntervalSec": 150
}
}Then:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginPermitNoticeService/checkQrCodeVerified
content-length: 88
x-line-session-id: <redacted auth session id>
x-lst: 150000Request payload:
[
{
"authSessionId": "<redacted auth session id>"
}
]The net-export does not include a usable response body for this request.
Request:
GET /api/operation/receive?localRev=947933&version=3.7.2&lastPartialFullSyncs=%7B%7D&language=en_USObserved SSE events of interest:
event: ping
data: null
event: connInfoRevision
data: 396
id: 947934
data: {"revision":"947934","createdTime":"1773625292915","type":40,"reqSeq":65421321,"param1":"<group MID>","param2":"605311845963661626","param3":"0"}
id: 947935
data: {"revision":"947935","createdTime":"1773625299390","type":25,"reqSeq":-1,"param1":"0","message":{"from":"<logged-in user MID>","to":"<group MID>","toType":2,"id":"605311879182811626","createdTime":"1773625299388","text":"\\u306a\\u306b\\u3092\\u3057\\u3066\\u3044\\u308b\\u306e","hasContent":false,"contentType":0,"contentMetadata":{},"sessionId":0,"reactions":[]}}
id: 947936
data: {"revision":"947936","createdTime":"1773625299460","type":55,"reqSeq":0,"param1":"<group MID>","param2":"<logged-in user MID>","param3":"605311879182811626"}
id: 947937
data: {"revision":"947937","createdTime":"1773625305500","type":25,"reqSeq":662642008,"param1":"0","message":{"from":"<logged-in user MID>","to":"<group MID>","toType":2,"id":"605311889450205372","createdTime":"1773625305497","text":"\\u30c6\\u30b9\\u30c8","hasContent":false,"contentType":0,"contentMetadata":{},"sessionId":0,"reactions":[]}}
id: 947938
data: {"revision":"947938","createdTime":"1773625305601","type":55,"reqSeq":0,"param1":"<group MID>","param2":"<logged-in user MID>","param3":"605311889450205372"}
id: 947939
data: {"revision":"947939","createdTime":"1773625309727","type":25,"reqSeq":662642009,"param1":"0","message":{"from":"<logged-in user MID>","to":"<second group MID>","toType":2,"id":"605311896362418782","createdTime":"1773625309725","text":"\\u30c6\\u30b9\\u30c8","hasContent":false,"contentType":0,"contentMetadata":{},"sessionId":0,"reactions":[]}}
This capture contains:
- login with a Letter Sealing on account
- direct message to a Letter Sealing off user
- group message into a mixed group
- logout
Observed request:
POST /api/talk/thrift/Talk/TalkService/getProfile
content-length: 3Request payload:
[2]Observed response:
{
"code": 10051,
"message": "RESPONSE_ERROR",
"data": {
"name": "TalkException",
"message": "TalkException",
"code": 1,
"reason": "Authentication Failed.",
"parameterMap": null
}
}Chrome then calls:
POST /api/talk/thrift/Talk/AuthService/logoutV2
content-length: 2Response:
{
"code": 0,
"message": "OK"
}Request:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginService/createSession
content-length: 4Request payload:
[{}]Response:
{
"code": 0,
"message": "OK",
"data": {
"authSessionId": "<redacted auth session id>"
}
}Request:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginService/createQrCode
content-length: 88Request payload:
[
{
"authSessionId": "<redacted auth session id>"
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"callbackUrl": "https://line.me/R/au/lgn/sq/<redacted auth session id>",
"longPollingMaxCount": 2,
"longPollingIntervalSec": 150
}
}Request:
POST /api/talk/thrift/LoginQrCode/SecondaryQrCodeLoginPermitNoticeService/checkQrCodeVerified
content-length: 88
x-line-session-id: <redacted auth session id>
x-lst: 150000Request payload:
[
{
"authSessionId": "<redacted auth session id>"
}
]Response:
- Not available in usable form in the net-export.
Observed precursor request:
POST /api/talk/thrift/Talk/TalkService/getRSAKeyInfo
content-length: 3Request payload:
[1]Response returns the RSA key material used to construct the encrypted loginV2.password field.
Request:
POST /api/talk/thrift/Talk/AuthService/loginV2
content-length: 569Request payload:
[
{
"type": 0,
"identityProvider": 1,
"identifier": "15349",
"password": "<app-encrypted blob>",
"keepLoggedIn": false,
"accessLocation": "",
"systemName": "Chrome",
"certificate": "<certificate from prior login>",
"verifier": "",
"secret": "",
"e2eeVersion": 1,
"modelName": ""
}
]Response headers of note:
set-cookie: lct=<redacted jwt>; path=/; samesite=none; secure; httponlyResponse body shape:
{
"code": 0,
"message": "OK",
"data": {
"type": 1,
"lastPrimaryBindTime": "1534608800980",
"tokenV3IssueResult": {
"accessToken": "<redacted jwt>",
"refreshToken": "<redacted refresh token>",
"durationUntilRefreshInSec": "...",
"loginSessionId": "...",
"tokenIssueTimeEpochSec": "..."
},
"mid": "<LSON user MID>"
}
}Request:
POST /api/talk/thrift/Talk/TalkService/negotiateE2EEPublicKey
content-length: 48
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
"<LSOFF user MID>"
]Response:
{
"code": 0,
"message": "OK",
"data": {
"allowedTypes": [],
"specVersion": -1
}
}Interpretation:
- Chrome asked whether an E2EE public key was usable for the LSOFF peer.
- The server did not provide a usable E2EE mode here.
Request:
POST /api/talk/thrift/Talk/TalkService/sendMessage
content-length: 274
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
1524162637,
{
"from": "<LSON user MID>",
"to": "<LSOFF user MID>",
"toType": 0,
"id": "local-1524162637",
"createdTime": "1773638909000",
"sessionId": 0,
"text": "テスト",
"contentType": 0,
"contentMetadata": {},
"hasContent": false
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"from": "<LSON user MID>",
"toType": 0,
"id": "605334711279812711",
"createdTime": "1773638908366",
"deliveredTime": "0",
"hasContent": false,
"contentType": 0,
"sessionId": 0,
"reactions": []
}
}First request:
POST /api/talk/thrift/Talk/TalkService/getLastE2EEGroupSharedKey
content-length: 50
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
1,
"<mixed group MID>"
]Response:
{
"code": 10051,
"message": "RESPONSE_ERROR",
"data": {
"name": "TalkException",
"message": "TalkException",
"code": 5,
"reason": "not found",
"parameterMap": null
}
}Second request:
POST /api/talk/thrift/Talk/TalkService/getLastE2EEPublicKeys
content-length: 48
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
"<mixed group MID>"
]Response:
{
"code": 10051,
"message": "RESPONSE_ERROR",
"data": {
"name": "TalkException",
"message": "TalkException",
"code": 98,
"reason": "member settings off",
"parameterMap": {}
}
}Interpretation:
- The group shared key is not available.
- At least one member has settings that prevent usable E2EE key retrieval.
Request:
POST /api/talk/thrift/Talk/TalkService/sendMessage
content-length: 274
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[
1524162638,
{
"from": "<LSON user MID>",
"to": "<mixed group MID>",
"toType": 2,
"id": "local-1524162638",
"createdTime": "1773638915000",
"sessionId": 0,
"text": "テスト",
"contentType": 0,
"contentMetadata": {},
"hasContent": false
}
]Response:
{
"code": 0,
"message": "OK",
"data": {
"from": "<LSON user MID>",
"toType": 2,
"id": "605334721933082899",
"createdTime": "1773638914873",
"deliveredTime": "0",
"hasContent": false,
"contentType": 0,
"sessionId": 0,
"reactions": []
}
}Request:
POST /api/talk/thrift/Talk/AuthService/logoutV2
content-length: 2
x-line-access: <redacted jwt>
cookie: lct=<redacted jwt>Request payload:
[]Response:
{
"code": 0,
"message": "OK"
}Request:
GET /api/operation/receive?localRev=949684&version=3.7.2&lastPartialFullSyncs=%7B%7D&language=en_USObserved SSE events of interest:
event: ping
data: null
event: connInfoRevision
data: 396
id: 949685
data: {"revision":"949685","createdTime":"1773638908368","type":25,"reqSeq":1524162637,"param1":"0","message":{"from":"<LSON user MID>","to":"<LSOFF user MID>","toType":0,"id":"605334711279812711","createdTime":"1773638908366","text":"\\u30c6\\u30b9\\u30c8","hasContent":false,"contentType":0,"contentMetadata":{},"sessionId":0,"reactions":[]}}
id: 949686
data: {"revision":"949686","createdTime":"1773638914875","type":25,"reqSeq":1524162638,"param1":"0","message":{"from":"<LSON user MID>","to":"<mixed group MID>","toType":2,"id":"605334721933082899","createdTime":"1773638914873","text":"\\u30c6\\u30b9\\u30c8","hasContent":false,"contentType":0,"contentMetadata":{},"sessionId":0,"reactions":[]}}
Important note:
- These
/receiveevents are the strongest confirmation that Chrome sent plain text successfully in both cases. - The
sendMessageresponses only confirm acceptance and message IDs; the/receivestream is where the actual text body appears.
The Letter Sealing on trace shows this exact sequence:
- Try E2EE-related lookup for the direct peer.
- Get no usable E2EE mode.
- Send plain
sendMessageanyway. - For the mixed group, try group-key lookup.
- Get
not foundandmember settings off. - Send plain
sendMessageanyway. - Confirm success through
/api/operation/receive.
That is the main protocol behavior this capture demonstrates.