package Encryption
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"errors"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
)
|
|
|
|
func DecryptData(password string, ciphertext []byte) ([]byte, error) {
|
|
var (
|
|
hashedKey []byte
|
|
iv []byte
|
|
encKey []byte
|
|
block cipher.Block
|
|
stream cipher.Stream
|
|
e error
|
|
)
|
|
hashedKey = CreateHash(password)
|
|
if len(ciphertext) == 0 {
|
|
return []byte{}, errors.New("Invalid length")
|
|
}
|
|
iv = ciphertext[:aes.BlockSize]
|
|
encKey = ciphertext[:32+aes.BlockSize][aes.BlockSize:]
|
|
ciphertext = ciphertext[aes.BlockSize+32:]
|
|
|
|
block, e = CreateKey(hashedKey)
|
|
if e != nil {
|
|
return []byte{}, e
|
|
}
|
|
|
|
stream = cipher.NewCFBDecrypter(block, iv)
|
|
stream.XORKeyStream(encKey, encKey)
|
|
|
|
for i := range encKey {
|
|
if encKey[i] != hashedKey[i] {
|
|
return []byte{}, errors.New("Incorrect Password")
|
|
}
|
|
}
|
|
|
|
stream.XORKeyStream(ciphertext, ciphertext)
|
|
return ciphertext, nil
|
|
}
|
|
|
|
func DecryptFile(password string, FilePath string) error {
|
|
var (
|
|
OldFilePath string
|
|
ciphertext []byte
|
|
plaintext []byte
|
|
plaintextFile *os.File
|
|
e error
|
|
)
|
|
OldFilePath = FilePath[:(len(FilePath) - 4)]
|
|
ciphertext, e = ioutil.ReadFile(FilePath)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
if len(ciphertext) < aes.BlockSize {
|
|
return errors.New("ciphertext too short")
|
|
}
|
|
|
|
plaintext, e = DecryptData(password, ciphertext)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
|
|
plaintextFile, e = os.Create(OldFilePath)
|
|
if e != nil {
|
|
return e
|
|
}
|
|
_, e = io.Copy(plaintextFile, bytes.NewReader(plaintext))
|
|
if e != nil {
|
|
return e
|
|
}
|
|
os.Remove(FilePath)
|
|
return nil
|
|
}
|
|
|
|
func DecryptAndReadFile(password string, FilePath string) (string, error) {
|
|
var (
|
|
ciphertext []byte
|
|
plaintext []byte
|
|
e error
|
|
)
|
|
ciphertext, e = ioutil.ReadFile(FilePath)
|
|
if e != nil {
|
|
return "", e
|
|
}
|
|
if len(ciphertext) < aes.BlockSize {
|
|
return "", errors.New("ciphertext too short")
|
|
}
|
|
|
|
plaintext, e = DecryptData(password, ciphertext)
|
|
if e != nil {
|
|
return "", e
|
|
}
|
|
return string(plaintext), nil
|
|
}
|