You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
About the encryption and the decryption of the socekt communication between the browser client and the node server #2618
Q: About the encryption and the decryption of the socekt communication between the browser client and the node server
For the privacy of users, it is now necessary to encrypt and decrypt the data between the browser client and the node server socekt communication.
By studying the source code of vscode, I found some code fragments related to data about the socekt communication, likebrowser/browserSocketFactory.tsandnode/ipc.net.ts.
I tried countless times, but all failed. I think the key of this question lies in the conversion of data types(like uint8Array, VSbuffer...)
What puzzles me is that when I convert the received buffer from the browser client (VsBuffer => string => VsBuffer) in the node/ipc.net.ts. The result of the buffer before and after the conversion is unexpected, the length of the VsBuffer is the same, but a small part of the converted Vsbuffer has changed. I guess it may be caused by garbled characters after being converted to string, so what is the coding scheme of the garbled characters, unlike ASCII, UTF-8, Unicode..., as shown below:
// some function about conversion // Vsbuffer => stringVsBuffer.toString()// string => Vsbuffer(built-in-method) VsBuffer.fromString(str: string)// string => Vsbuffer(use)functionstr2buff(str: string): VSBuffer{letarr=[]for(leti=0,j=str.length;i<j;++i){arr.push(str.charCodeAt(i))}returnVSBuffer.wrap(newUint8Array(arr))}
But if I use the built-in-method of the Vsbuffer to convert (VsBuffer => string => VsBuffer), the length and buffer content of the buffer before and after is inconsistent.
Now my thoughts are blocked, maybe. How can I complete this function by modifying the source code of vscode?
I'm fairly new to the VSCode internals - but if it works how I think it does, shouldn't we have transport-layer encryption provided by the websocket if we have a cert provided?
I'm fairly new to the VSCode internals - but if it works how I think it does, shouldn't we have transport-layer encryption provided by the websocket if we have a cert provided?
You mean the transport layer encryption at the webSocket, I know, but I want to encrypt data on the application layer😅
There is an abstraction on top of the messages sent across the socket. There is a header with some information then a body after that (you can see the documentation for this in ipc.net.ts). Probably trying to convert the header portion to a string is causing the issue.
There are further abstractions on top of that in some cases, like with channels which add their own header and body as well. There may be others but those are all the ones I know of.
In fact I don't think there's any guarantee the body is a string so any kind of general conversion is probably going to have issues.
Now I have completed the first simply encryption, split the client data into header, body, footer, then encrypt the body data(code fragment), and then divide the body into header, body, and footer when the server receives it in the _acceptChunk function, and then fire the body(this.onData.fire(body)) After decrypt the body data and splice it back.
However, this kind of websocket encryption is successful under a certain amount of code (about 1200 lines of code), but too much code will trigger the reconnection mechanism due to acceptChunck's block transmission.
Is there any way to solve this problem or other ideas of encryption? Help😅
Couldn't you encrypt and decrypt the entire message without having to do any splitting?
If you do not split, because of some special identifiers of header and footer, the encrypted data will not be successfully decrypted on the server. Now I am using CryptoJS AES encryption and decryption. Since the string can be encrypted and decrypted directly after splitting, there is no need to consider converting to base64.
The problem now lies in the acceptChunck's block transmission when the amount of code is large(about 1200+ lines of code). I think this splitting may have limitations.
Are there any other good encryption methods to fix?🥺
// encrypt and decrypt after splittingimport*asCryptoJSfrom'crypto-js'// 1. the encrypt func in the clientfunctionencrypt(word: string): string{letencJson=CryptoJS.AES.encrypt(JSON.stringify(word),key).toString()letencData=CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(encJson))returnencData}//2. the decrypt func in the node serverfunctiondecrypt(word: string): string{letdecData=CryptoJS.enc.Base64.parse(word).toString(CryptoJS.enc.Utf8)letbytes=CryptoJS.AES.decrypt(decData,key).toString(CryptoJS.enc.Utf8)returnJSON.parse(bytes)}
I think splitting will be dangerous because there's no guarantee a chunk has a header or a body. It could be half a header or have multiple headers and bodies or not have any headers and bodies at all or have a body that itself also has a header and a body, etc.
You might have success if you encrypt and decrypt at the points where the socket sends and receives messages.
Activity
oxy commentedon Jan 22, 2021
I'm fairly new to the VSCode internals - but if it works how I think it does, shouldn't we have transport-layer encryption provided by the websocket if we have a cert provided?
OFEII commentedon Jan 25, 2021
You mean the transport layer encryption at the webSocket, I know, but I want to encrypt data on the application layer😅
code-asher commentedon Jan 25, 2021
There is an abstraction on top of the messages sent across the socket. There is a header with some information then a body after that (you can see the documentation for this in
ipc.net.ts). Probably trying to convert the header portion to a string is causing the issue.There are further abstractions on top of that in some cases, like with channels which add their own header and body as well. There may be others but those are all the ones I know of.
code-asher commentedon Jan 25, 2021
In fact I don't think there's any guarantee the body is a string so any kind of general conversion is probably going to have issues.
OFEII commentedon Feb 18, 2021
Now I have completed the first simply encryption, split the client data into header, body, footer, then encrypt the body data(code fragment), and then divide the body into header, body, and footer when the server receives it in the _acceptChunk function, and then fire the body(
this.onData.fire(body)) After decrypt the body data and splice it back.However, this kind of websocket encryption is successful under a certain amount of code (about 1200 lines of code), but too much code will trigger the reconnection mechanism due to acceptChunck's block transmission.
Is there any way to solve this problem or other ideas of encryption? Help😅

code-asher commentedon Feb 18, 2021
OFEII commentedon Feb 19, 2021
If you do not split, because of some special identifiers of header and footer, the encrypted data will not be successfully decrypted on the server. Now I am using CryptoJS AES encryption and decryption. Since the string can be encrypted and decrypted directly after splitting, there is no need to consider converting to base64.
The problem now lies in the acceptChunck's block transmission when the amount of code is large(about 1200+ lines of code). I think this splitting may have limitations.
Are there any other good encryption methods to fix?🥺
code-asher commentedon Feb 22, 2021
I think splitting will be dangerous because there's no guarantee a chunk has a header or a body. It could be half a header or have multiple headers and bodies or not have any headers and bodies at all or have a body that itself also has a header and a body, etc.
You might have success if you encrypt and decrypt at the points where the socket sends and receives messages.
Maybe here:
https://github.com/cdr/code-server/blob/fc6d123da59a4e5a675ac8e080f66e032ba01a1b/lib/vscode/src/vs/base/parts/ipc/node/ipc.net.ts#L31
And here:
https://github.com/cdr/code-server/blob/fc6d123da59a4e5a675ac8e080f66e032ba01a1b/lib/vscode/src/vs/base/parts/ipc/node/ipc.net.ts#L64
Where
encryptanddecryptare capable of encrypting and decrypting an arbitraryBuffer.code-asher commentedon Feb 22, 2021
I'm going to move this to a discussion, please feel free to continue commenting there!