crypto_libsodium.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. package crypto
  2. import (
  3. "bufio"
  4. "errors"
  5. "github.com/ente-io/cli/utils/encoding"
  6. "golang.org/x/crypto/nacl/box"
  7. "golang.org/x/crypto/nacl/secretbox"
  8. "io"
  9. "log"
  10. "os"
  11. )
  12. //func EncryptChaCha20poly1305LibSodium(data []byte, key []byte) ([]byte, []byte, error) {
  13. // var buf bytes.Buffer
  14. // encoder := sodium.MakeSecretStreamXCPEncoder(sodium.SecretStreamXCPKey{Bytes: key}, &buf)
  15. // _, err := encoder.WriteAndClose(data)
  16. // if err != nil {
  17. // log.Println("Failed to write to encoder", err)
  18. // return nil, nil, err
  19. // }
  20. // return buf.Bytes(), encoder.Header().Bytes, nil
  21. //}
  22. // EncryptChaCha20poly1305 encrypts the given data using the ChaCha20-Poly1305 algorithm.
  23. // Parameters:
  24. // - data: The plaintext data as a byte slice.
  25. // - key: The key for encryption as a byte slice.
  26. //
  27. // Returns:
  28. // - A byte slice representing the encrypted data.
  29. // - A byte slice representing the header of the encrypted data.
  30. // - An error object, which is nil if no error occurs.
  31. func EncryptChaCha20poly1305(data []byte, key []byte) ([]byte, []byte, error) {
  32. encryptor, header, err := NewEncryptor(key)
  33. if err != nil {
  34. return nil, nil, err
  35. }
  36. encoded, err := encryptor.Push(data, TagFinal)
  37. if err != nil {
  38. return nil, nil, err
  39. }
  40. return encoded, header, nil
  41. }
  42. // decryptChaCha20poly1305 decrypts the given data using the ChaCha20-Poly1305 algorithm.
  43. // Parameters:
  44. // - data: The encrypted data as a byte slice.
  45. // - key: The key for decryption as a byte slice.
  46. // - nonce: The nonce for decryption as a byte slice.
  47. //
  48. // Returns:
  49. // - A byte slice representing the decrypted data.
  50. // - An error object, which is nil if no error occurs.
  51. //func decryptChaCha20poly1305LibSodium(data []byte, key []byte, nonce []byte) ([]byte, error) {
  52. // reader := bytes.NewReader(data)
  53. // header := sodium.SecretStreamXCPHeader{Bytes: nonce}
  54. // decoder, err := sodium.MakeSecretStreamXCPDecoder(
  55. // sodium.SecretStreamXCPKey{Bytes: key},
  56. // reader,
  57. // header)
  58. // if err != nil {
  59. // log.Println("Failed to make secret stream decoder", err)
  60. // return nil, err
  61. // }
  62. // // Buffer to store the decrypted data
  63. // decryptedData := make([]byte, len(data))
  64. // n, err := decoder.Read(decryptedData)
  65. // if err != nil && err != io.EOF {
  66. // log.Println("Failed to read from decoder", err)
  67. // return nil, err
  68. // }
  69. // return decryptedData[:n], nil
  70. //}
  71. func decryptChaCha20poly1305(data []byte, key []byte, nonce []byte) ([]byte, error) {
  72. decryptor, err := NewDecryptor(key, nonce)
  73. if err != nil {
  74. return nil, err
  75. }
  76. decoded, tag, err := decryptor.Pull(data)
  77. if tag != TagFinal {
  78. return nil, errors.New("invalid tag")
  79. }
  80. if err != nil {
  81. return nil, err
  82. }
  83. return decoded, nil
  84. }
  85. //func SecretBoxOpenLibSodium(c []byte, n []byte, k []byte) ([]byte, error) {
  86. // var cp sodium.Bytes = c
  87. // res, err := cp.SecretBoxOpen(sodium.SecretBoxNonce{Bytes: n}, sodium.SecretBoxKey{Bytes: k})
  88. // return res, err
  89. //}
  90. func SecretBoxOpenBase64(cipher string, nonce string, k []byte) ([]byte, error) {
  91. return SecretBoxOpen(encoding.DecodeBase64(cipher), encoding.DecodeBase64(nonce), k)
  92. }
  93. func SecretBoxOpen(c []byte, n []byte, k []byte) ([]byte, error) {
  94. // Check for valid lengths of nonce and key
  95. if len(n) != 24 || len(k) != 32 {
  96. return nil, ErrOpenBox
  97. }
  98. var nonce [24]byte
  99. var key [32]byte
  100. copy(nonce[:], n)
  101. copy(key[:], k)
  102. // Decrypt the message using Go's nacl/secretbox
  103. decrypted, ok := secretbox.Open(nil, c, &nonce, &key)
  104. if !ok {
  105. return nil, ErrOpenBox
  106. }
  107. return decrypted, nil
  108. }
  109. //func SealedBoxOpenLib(cipherText []byte, publicKey, masterSecret []byte) ([]byte, error) {
  110. // var cp sodium.Bytes = cipherText
  111. // om, err := cp.SealedBoxOpen(sodium.BoxKP{
  112. // PublicKey: sodium.BoxPublicKey{Bytes: publicKey},
  113. // SecretKey: sodium.BoxSecretKey{Bytes: masterSecret},
  114. // })
  115. // if err != nil {
  116. // return nil, fmt.Errorf("failed to open sealed box: %v", err)
  117. // }
  118. // return om, nil
  119. //}
  120. func SealedBoxOpen(cipherText, publicKey, masterSecret []byte) ([]byte, error) {
  121. if len(cipherText) < BoxSealBytes {
  122. return nil, ErrOpenBox
  123. }
  124. // Extract ephemeral public key from the ciphertext
  125. var ephemeralPublicKey [32]byte
  126. copy(ephemeralPublicKey[:], publicKey[:32])
  127. // Extract ephemeral public key from the ciphertext
  128. var masterKey [32]byte
  129. copy(masterKey[:], masterSecret[:32])
  130. // Decrypt the message using nacl/box
  131. decrypted, ok := box.OpenAnonymous(nil, cipherText, &ephemeralPublicKey, &masterKey)
  132. if !ok {
  133. return nil, ErrOpenBox
  134. }
  135. return decrypted, nil
  136. }
  137. func DecryptFile(encryptedFilePath string, decryptedFilePath string, key, nonce []byte) error {
  138. inputFile, err := os.Open(encryptedFilePath)
  139. if err != nil {
  140. return err
  141. }
  142. defer inputFile.Close()
  143. outputFile, err := os.Create(decryptedFilePath)
  144. if err != nil {
  145. return err
  146. }
  147. defer outputFile.Close()
  148. reader := bufio.NewReader(inputFile)
  149. writer := bufio.NewWriter(outputFile)
  150. decryptor, err := NewDecryptor(key, nonce)
  151. if err != nil {
  152. return err
  153. }
  154. buf := make([]byte, decryptionBufferSize+XChaCha20Poly1305IetfABYTES)
  155. for {
  156. readCount, err := reader.Read(buf)
  157. if err != nil && err != io.EOF {
  158. log.Println("Failed to read from input file", err)
  159. return err
  160. }
  161. if readCount == 0 {
  162. break
  163. }
  164. n, tag, errErr := decryptor.Pull(buf[:readCount])
  165. if errErr != nil && errErr != io.EOF {
  166. log.Println("Failed to read from decoder", errErr)
  167. return errErr
  168. }
  169. if _, err := writer.Write(n); err != nil {
  170. log.Println("Failed to write to output file", err)
  171. return err
  172. }
  173. if errErr == io.EOF {
  174. break
  175. }
  176. if tag == TagFinal {
  177. break
  178. }
  179. }
  180. if err := writer.Flush(); err != nil {
  181. log.Println("Failed to flush writer", err)
  182. return err
  183. }
  184. return nil
  185. }
  186. //func DecryptFileLib(encryptedFilePath string, decryptedFilePath string, key, nonce []byte) error {
  187. // inputFile, err := os.Open(encryptedFilePath)
  188. // if err != nil {
  189. // return err
  190. // }
  191. // defer inputFile.Close()
  192. //
  193. // outputFile, err := os.Create(decryptedFilePath)
  194. // if err != nil {
  195. // return err
  196. // }
  197. // defer outputFile.Close()
  198. //
  199. // reader := bufio.NewReader(inputFile)
  200. // writer := bufio.NewWriter(outputFile)
  201. //
  202. // header := sodium.SecretStreamXCPHeader{Bytes: nonce}
  203. // decoder, err := sodium.MakeSecretStreamXCPDecoder(
  204. // sodium.SecretStreamXCPKey{Bytes: key},
  205. // reader,
  206. // header)
  207. // if err != nil {
  208. // log.Println("Failed to make secret stream decoder", err)
  209. // return err
  210. // }
  211. //
  212. // buf := make([]byte, decryptionBufferSize)
  213. // for {
  214. // n, errErr := decoder.Read(buf)
  215. // if errErr != nil && errErr != io.EOF {
  216. // log.Println("Failed to read from decoder", errErr)
  217. // return errErr
  218. // }
  219. // if n == 0 {
  220. // break
  221. // }
  222. // if _, err := writer.Write(buf[:n]); err != nil {
  223. // log.Println("Failed to write to output file", err)
  224. // return err
  225. // }
  226. // if errErr == io.EOF {
  227. // break
  228. // }
  229. // }
  230. // if err := writer.Flush(); err != nil {
  231. // log.Println("Failed to flush writer", err)
  232. // return err
  233. // }
  234. // return nil
  235. //}