Explorar o código

add Encrypt method

Steven Schobert %!s(int64=9) %!d(string=hai) anos
pai
achega
8310186b85
Modificáronse 1 ficheiros con 79 adicións e 0 borrados
  1. 79 0
      rncryptor.go

+ 79 - 0
rncryptor.go

@@ -3,6 +3,7 @@ package rncryptor
 import(
   "bytes"
   "errors"
+  "crypto/rand"
   "crypto/sha1"
   "crypto/sha256"
   "crypto/hmac"
@@ -55,3 +56,81 @@ func Decrypt(password string, data []byte) ([]byte, error) {
 
   return decrypted[:(length - unpadding)], nil
 }
+
+func Encrypt(password string, data []byte) ([]byte, error) {
+  encSalt, encSaltErr := RandBytes(8)
+  if encSaltErr != nil {
+    return nil, encSaltErr
+  }
+
+  hmacSalt, hmacSaltErr := RandBytes(8)
+  if hmacSaltErr != nil {
+    return nil, hmacSaltErr
+  }
+
+  iv, ivErr := RandBytes(16)
+  if ivErr != nil {
+    return nil, ivErr
+  }
+
+  encrypted, encErr := EncryptWithOptions(password, data, encSalt, hmacSalt, iv)
+  if encErr != nil {
+    return nil, encErr
+  }
+  return encrypted, nil
+}
+
+func EncryptWithOptions(password string, data, encSalt, hmacSalt, iv []byte) ([]byte, error) {
+  if len(password) < 1 {
+    return nil, errors.New("Password cannot be empty")
+  }
+
+  encKey := pbkdf2.Key([]byte(password), encSalt, 10000, 32, sha1.New)
+  hmacKey := pbkdf2.Key([]byte(password), hmacSalt, 10000, 32, sha1.New)
+
+  cipherText := make([]byte, len(data))
+  copy(cipherText, data)
+
+  version := byte(3)
+  options := byte(1)
+
+  msg := make([]byte, 0)
+  msg = append(msg, version)
+  msg = append(msg, options)
+  msg = append(msg, encSalt...)
+  msg = append(msg, hmacSalt...)
+  msg = append(msg, iv...)
+
+  cipherBlock, cipherBlockErr := aes.NewCipher(encKey)
+  if cipherBlockErr != nil {
+    return nil, cipherBlockErr
+  }
+
+  // padd text for encryption
+  blockSize := cipherBlock.BlockSize()
+  padding := blockSize - len(cipherText)%blockSize
+  padText := bytes.Repeat([]byte{byte(padding)}, padding)
+  cipherText = append(cipherText, padText...)
+
+  encrypter := cipher.NewCBCEncrypter(cipherBlock, iv)
+  encrypter.CryptBlocks(cipherText, cipherText)
+
+  msg = append(msg, cipherText...)
+
+  hmacSrc := hmac.New(sha256.New, hmacKey)
+  hmacSrc.Write(msg)
+  hmacVal := hmacSrc.Sum(nil)
+
+  msg = append(msg, hmacVal...)
+
+  return msg, nil
+}
+
+func RandBytes(num int64) ([]byte, error) {
+  bits := make([]byte, num)
+  _, err := rand.Read(bits)
+  if err != nil {
+    return nil, err
+  }
+  return bits, nil
+}