encryption.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package ncutils
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "fmt"
  6. "io"
  7. "golang.org/x/crypto/nacl/box"
  8. "golang.org/x/exp/slog"
  9. )
  10. const (
  11. chunkSize = 16000 // 16000 bytes max message size
  12. )
  13. // BoxEncrypt - encrypts traffic box
  14. func BoxEncrypt(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
  15. var nonce [24]byte // 192 bits of randomization
  16. if _, err := io.ReadFull(rand.Reader, nonce[:]); err != nil {
  17. return nil, err
  18. }
  19. encrypted := box.Seal(nonce[:], message, &nonce, recipientPubKey, senderPrivateKey)
  20. return encrypted, nil
  21. }
  22. // BoxDecrypt - decrypts traffic box
  23. func BoxDecrypt(encrypted []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
  24. var decryptNonce [24]byte
  25. copy(decryptNonce[:], encrypted[:24])
  26. out := []byte{}
  27. decrypted, ok := box.Open(out, encrypted[24:], &decryptNonce, senderPublicKey, recipientPrivateKey)
  28. if !ok {
  29. slog.Debug("could not decrypt message", "out", out)
  30. return nil, fmt.Errorf("could not decrypt message, %v", encrypted)
  31. }
  32. return decrypted, nil
  33. }
  34. // Chunk - chunks a message and encrypts each chunk
  35. func Chunk(message []byte, recipientPubKey *[32]byte, senderPrivateKey *[32]byte) ([]byte, error) {
  36. var chunks [][]byte
  37. for i := 0; i < len(message); i += chunkSize {
  38. end := i + chunkSize
  39. if end > len(message) {
  40. end = len(message)
  41. }
  42. encryptedMsgSlice, err := BoxEncrypt(message[i:end], recipientPubKey, senderPrivateKey)
  43. if err != nil {
  44. return nil, err
  45. }
  46. chunks = append(chunks, encryptedMsgSlice)
  47. }
  48. chunkedMsg, err := convertBytesToMsg(chunks) // encode the array into some bytes to decode on receiving end
  49. if err != nil {
  50. return nil, err
  51. }
  52. return chunkedMsg, nil
  53. }
  54. // DeChunk - "de" chunks and decrypts a message
  55. func DeChunk(chunkedMsg []byte, senderPublicKey *[32]byte, recipientPrivateKey *[32]byte) ([]byte, error) {
  56. chunks, err := convertMsgToBytes(chunkedMsg) // convert the message to it's original chunks form
  57. if err != nil {
  58. return nil, err
  59. }
  60. var totalMsg []byte
  61. for i := range chunks {
  62. decodedMsg, err := BoxDecrypt(chunks[i], senderPublicKey, recipientPrivateKey)
  63. if err != nil {
  64. return nil, err
  65. }
  66. totalMsg = append(totalMsg, decodedMsg...)
  67. }
  68. return totalMsg, nil
  69. }
  70. // == private ==
  71. var splitKey = []byte("|(,)(,)|")
  72. // ConvertMsgToBytes - converts a message (MQ) to it's chunked version
  73. // decode action
  74. func convertMsgToBytes(msg []byte) ([][]byte, error) {
  75. splitMsg := bytes.Split(msg, splitKey)
  76. return splitMsg, nil
  77. }
  78. // ConvertBytesToMsg - converts the chunked message into a MQ message
  79. // encode action
  80. func convertBytesToMsg(b [][]byte) ([]byte, error) {
  81. var buffer []byte // allocate a buffer with adequate sizing
  82. for i := range b { // append bytes to it with key
  83. buffer = append(buffer, b[i]...)
  84. if i != len(b)-1 {
  85. buffer = append(buffer, splitKey...)
  86. }
  87. }
  88. return buffer, nil
  89. }