mirror of
				https://github.com/gravitl/netmaker.git
				synced 2025-10-31 04:06:37 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package ncutils
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"crypto/rand"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 
 | |
| 	"golang.org/x/crypto/nacl/box"
 | |
| )
 | |
| 
 | |
| const (
 | |
| 	chunkSize = 16000 // 16000 bytes max message size
 | |
| )
 | |
| 
 | |
| // BoxEncrypt - encrypts traffic box
 | |
| func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
 | |
| 	var nonce [24]byte // 192 bits of randomization
 | |
| 	if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
 | |
| 	return encrypted, nil
 | |
| }
 | |
| 
 | |
| // BoxDecrypt - decrypts traffic box
 | |
| func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
 | |
| 	var decryptNonce [24]byte
 | |
| 	copy(decryptNonce[:], encrypted[:24])
 | |
| 	decrypted, ok := box.Open(nil, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
 | |
| 	if !ok {
 | |
| 		return nil, fmt.Errorf("could not decrypt message, %v", encrypted)
 | |
| 	}
 | |
| 	return decrypted, nil
 | |
| }
 | |
| 
 | |
| // Chunk - chunks a message and encrypts each chunk
 | |
| func Chunk(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
 | |
| 	var chunks [][]byte
 | |
| 	for i := 0; i < len(message); i += chunkSize {
 | |
| 		end := i + chunkSize
 | |
| 
 | |
| 		if end > len(message) {
 | |
| 			end = len(message)
 | |
| 		}
 | |
| 
 | |
| 		encryptedMsgSlice, err := BoxEncrypt(message[i:end], recipientPubKey, senderPrivateKey)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		chunks = append(chunks, encryptedMsgSlice)
 | |
| 	}
 | |
| 
 | |
| 	chunkedMsg, err := convertBytesToMsg(chunks) // encode the array into some bytes to decode on receiving end
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return chunkedMsg, nil
 | |
| }
 | |
| 
 | |
| // DeChunk - "de" chunks and decrypts a message
 | |
| func DeChunk(chunkedMsg []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
 | |
| 	chunks, err := convertMsgToBytes(chunkedMsg) // convert the message to it's original chunks form
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	var totalMsg []byte
 | |
| 	for i := range chunks {
 | |
| 		decodedMsg, err := BoxDecrypt(chunks[i], senderPublicKey, recipientPrivateKey)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		totalMsg = append(totalMsg, decodedMsg...)
 | |
| 	}
 | |
| 	return totalMsg, nil
 | |
| }
 | |
| 
 | |
| // == private ==
 | |
| 
 | |
| var splitKey = []byte("|(,)(,)|")
 | |
| 
 | |
| // ConvertMsgToBytes - converts a message (MQ) to it's chunked version
 | |
| // decode action
 | |
| func convertMsgToBytes(msg []byte) ([][]byte, error) {
 | |
| 	splitMsg := bytes.Split(msg, splitKey)
 | |
| 	return splitMsg, nil
 | |
| }
 | |
| 
 | |
| // ConvertBytesToMsg - converts the chunked message into a MQ message
 | |
| // encode action
 | |
| func convertBytesToMsg(b [][]byte) ([]byte, error) {
 | |
| 
 | |
| 	var buffer []byte  // allocate a buffer with adequate sizing
 | |
| 	for i := range b { // append bytes to it with key
 | |
| 		buffer = append(buffer, b[i]...)
 | |
| 		if i != len(b)-1 {
 | |
| 			buffer = append(buffer, splitKey...)
 | |
| 		}
 | |
| 	}
 | |
| 	return buffer, nil
 | |
| }
 | 
