C/S demo with RSA and AES Algorithm
This program is my homework for the IoT course, demonstrating the use of symmetric encryption AES and asymmetric encryption RSA.
Communication Process
Server
- Create a socket and listen for TCP connections.
- Upon receiving a connection, perform corresponding operations based on the client's request:
utils.PacketTypeInit: Encrypt its own RSA public key with the pre-shared AES key and send it to the client.utils.PacketTypeComm: Decrypt and print the message sent by the client usingRSA-OAEPwith the private key, then encrypt its replyment with a self-made signature algorithm using the RSA private key and send it.
- When the client actively disconnects, one processing ends.
Client
- Establish a TCP connection to the server address.
- Send a
utils.PacketTypeInitpacket to the server to request the RSA key. - Continuously send
Helloto the server usingEncryptOAEPwhile decrypting and printing the message sent by server with its public key using the self-made signature algorithm. - When the user manually terminates, close the connection to the server.
Packet Protocol
The overall encapsulation is defined in utils/packet.go.
0 15 23
┌─────────┬────┬──────────────┐
│ len │type│ ... data ... │
└─────────┴────┴──────────────┘
len
The length of the packet without itself.
type
Defined in utils/packet.go.
const (
PacketTypeInit PacketType = iota // PacketTypeInit pass RSA pubkey by AES pre-shared key
PacketTypeComm // PacketTypeComm normal communication
PacketTypeTop // PacketTypeTop for valid checking
)
data
The payload, whose type is described by the type field.
PacketTypeInit
Defined in utils/packet_init.go.
0 7 23 87
┌────┬────────┬─────────────────┬──────────────────────┐
│type│ length │ pub key crc64 │ x509rsapubkey │
└────┴────────┴─────────────────┴──────────────────────┘
- type:
PacketInitTypeReqorPacketInitTypeAck - length: length of
x509rsapubkey
PacketTypeComm
The whole data field is encrypted by RSA and can fill in with any data, which is plain text in this demo.
Interesting Points
The Implementation of Base16384
Base16384 is a base64-like algorithm designed by me. It can encode binary file to printable utf16be, and vice versa.
In this demo, the RSA Private Key and AES key is saved and passed by base16384 format.
The Usage of Raw RSA Encrypting Method
In the file utils/rsa.go, I use go:linkname to hook the private function of crypto/rsa library and realized a self-made signature algorithm that can get the decoding result but not just verify whether it is valid (unlike the official method rsa.VerifyPKCS1v15).
Demo
See the video below.
https://github.com/fumiama/aes-rsa-tcp-demo/assets/41315874/e4f6522b-e147-4a2f-add3-3a2abb90e96b