Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
3.5 KiB

  1. package Seeder
  2. // THIS FILE IS ONLY USED FOR SEEDING DATA DURING DEVELOPMENT
  3. import (
  4. "bytes"
  5. "crypto/aes"
  6. "crypto/cipher"
  7. "crypto/hmac"
  8. "crypto/rand"
  9. "crypto/rsa"
  10. "crypto/sha256"
  11. "encoding/base64"
  12. "fmt"
  13. "hash"
  14. "golang.org/x/crypto/pbkdf2"
  15. )
  16. type aesKey struct {
  17. Key []byte
  18. Iv []byte
  19. }
  20. func (key aesKey) encode() string {
  21. return base64.StdEncoding.EncodeToString(key.Key)
  22. }
  23. // Appends padding.
  24. func pkcs7Padding(data []byte, blocklen int) ([]byte, error) {
  25. var (
  26. padlen int = 1
  27. pad []byte
  28. )
  29. if blocklen <= 0 {
  30. return nil, fmt.Errorf("invalid blocklen %d", blocklen)
  31. }
  32. for ((len(data) + padlen) % blocklen) != 0 {
  33. padlen = padlen + 1
  34. }
  35. pad = bytes.Repeat([]byte{byte(padlen)}, padlen)
  36. return append(data, pad...), nil
  37. }
  38. // pkcs7strip remove pkcs7 padding
  39. func pkcs7strip(data []byte, blockSize int) ([]byte, error) {
  40. var (
  41. length int
  42. padLen int
  43. ref []byte
  44. )
  45. length = len(data)
  46. if length == 0 {
  47. return nil, fmt.Errorf("pkcs7: Data is empty")
  48. }
  49. if (length % blockSize) != 0 {
  50. return nil, fmt.Errorf("pkcs7: Data is not block-aligned")
  51. }
  52. padLen = int(data[length-1])
  53. ref = bytes.Repeat([]byte{byte(padLen)}, padLen)
  54. if padLen > blockSize || padLen == 0 || !bytes.HasSuffix(data, ref) {
  55. return nil, fmt.Errorf("pkcs7: Invalid padding")
  56. }
  57. return data[:length-padLen], nil
  58. }
  59. func GenerateAesKey() (aesKey, error) {
  60. var (
  61. saltBytes []byte = []byte{}
  62. password []byte
  63. seed []byte
  64. iv []byte
  65. err error
  66. )
  67. password = make([]byte, 64)
  68. _, err = rand.Read(password)
  69. if err != nil {
  70. return aesKey{}, err
  71. }
  72. seed = make([]byte, 64)
  73. _, err = rand.Read(seed)
  74. if err != nil {
  75. return aesKey{}, err
  76. }
  77. iv = make([]byte, 16)
  78. _, err = rand.Read(iv)
  79. if err != nil {
  80. return aesKey{}, err
  81. }
  82. return aesKey{
  83. Key: pbkdf2.Key(
  84. password,
  85. saltBytes,
  86. 1000,
  87. 32,
  88. func() hash.Hash { return hmac.New(sha256.New, seed) },
  89. ),
  90. Iv: iv,
  91. }, nil
  92. }
  93. func (key aesKey) aesEncrypt(plaintext []byte) ([]byte, error) {
  94. var (
  95. bPlaintext []byte
  96. ciphertext []byte
  97. block cipher.Block
  98. err error
  99. )
  100. bPlaintext, err = pkcs7Padding(plaintext, 16)
  101. block, err = aes.NewCipher(key.Key)
  102. if err != nil {
  103. return []byte{}, err
  104. }
  105. ciphertext = make([]byte, len(bPlaintext))
  106. mode := cipher.NewCBCEncrypter(block, key.Iv)
  107. mode.CryptBlocks(ciphertext, bPlaintext)
  108. ciphertext = append(key.Iv, ciphertext...)
  109. return ciphertext, nil
  110. }
  111. func (key aesKey) aesDecrypt(ciphertext []byte) ([]byte, error) {
  112. var (
  113. plaintext []byte
  114. iv []byte
  115. block cipher.Block
  116. err error
  117. )
  118. iv = ciphertext[:aes.BlockSize]
  119. plaintext = ciphertext[aes.BlockSize:]
  120. block, err = aes.NewCipher(key.Key)
  121. if err != nil {
  122. return []byte{}, err
  123. }
  124. decMode := cipher.NewCBCDecrypter(block, iv)
  125. decMode.CryptBlocks(plaintext, plaintext)
  126. return plaintext, nil
  127. }
  128. // EncryptWithPublicKey encrypts data with public key
  129. func EncryptWithPublicKey(msg []byte, pub *rsa.PublicKey) []byte {
  130. var (
  131. hash hash.Hash
  132. )
  133. hash = sha256.New()
  134. ciphertext, err := rsa.EncryptOAEP(hash, rand.Reader, pub, msg, nil)
  135. if err != nil {
  136. panic(err)
  137. }
  138. return ciphertext
  139. }
  140. // DecryptWithPrivateKey decrypts data with private key
  141. func decryptWithPrivateKey(ciphertext []byte, priv *rsa.PrivateKey) ([]byte, error) {
  142. var (
  143. hash hash.Hash
  144. plaintext []byte
  145. err error
  146. )
  147. hash = sha256.New()
  148. plaintext, err = rsa.DecryptOAEP(hash, rand.Reader, priv, ciphertext, nil)
  149. if err != nil {
  150. return plaintext, err
  151. }
  152. return plaintext, nil
  153. }