encryption.go 2.7 KB

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