v0.0.77
This commit is contained in:
parent
36ed474bfe
commit
be4de07eb8
@ -1,6 +1,7 @@
|
|||||||
package cmdext
|
package cmdext
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -196,3 +197,30 @@ func TestPartialReadUnflushedStderr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListener(t *testing.T) {
|
||||||
|
|
||||||
|
_, err := Runner("python").
|
||||||
|
Arg("-c").
|
||||||
|
Arg("import sys;" +
|
||||||
|
"import time;" +
|
||||||
|
"print(\"message 1\", flush=True);" +
|
||||||
|
"time.sleep(1);" +
|
||||||
|
"print(\"message 2\", flush=True);" +
|
||||||
|
"time.sleep(1);" +
|
||||||
|
"print(\"message 3\", flush=True);" +
|
||||||
|
"time.sleep(1);" +
|
||||||
|
"print(\"message 4\", file=sys.stderr, flush=True);" +
|
||||||
|
"time.sleep(1);" +
|
||||||
|
"print(\"message 5\", flush=True);" +
|
||||||
|
"time.sleep(1);" +
|
||||||
|
"print(\"final\");").
|
||||||
|
ListenStdout(func(s string) { fmt.Printf("@@STDOUT <<- %v (%v)\n", s, time.Now().Format(time.RFC3339Nano)) }).
|
||||||
|
ListenStderr(func(s string) { fmt.Printf("@@STDERR <<- %v (%v)\n", s, time.Now().Format(time.RFC3339Nano)) }).
|
||||||
|
Timeout(10 * time.Second).
|
||||||
|
Run()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
110
cryptext/aes.go
110
cryptext/aes.go
@ -1,10 +1,13 @@
|
|||||||
package cryptext
|
package cryptext
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"crypto/sha256"
|
||||||
|
"encoding/base32"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"golang.org/x/crypto/scrypt"
|
"golang.org/x/crypto/scrypt"
|
||||||
"io"
|
"io"
|
||||||
@ -12,35 +15,88 @@ import (
|
|||||||
|
|
||||||
// https://stackoverflow.com/a/18819040/1761622
|
// https://stackoverflow.com/a/18819040/1761622
|
||||||
|
|
||||||
func EncryptAESSimple(password, text []byte) ([]byte, error) {
|
type aesPayload struct {
|
||||||
|
Salt []byte `json:"s"`
|
||||||
|
IV []byte `json:"i"`
|
||||||
|
Data []byte `json:"d"`
|
||||||
|
Rounds int `json:"r"`
|
||||||
|
Version uint `json:"v"`
|
||||||
|
Algorithm string `json:"a"`
|
||||||
|
}
|
||||||
|
|
||||||
key, err := scrypt.Key(password, nil, 32768, 8, 1, 32) // this is not 100% correct, rounds too low and salt is missing
|
func EncryptAESSimple(password []byte, data []byte, rounds int) (string, error) {
|
||||||
|
|
||||||
|
salt := make([]byte, 8)
|
||||||
|
_, err := io.ReadFull(rand.Reader, salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := scrypt.Key(password, salt, rounds, 8, 1, 32)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
b := base64.StdEncoding.EncodeToString(text)
|
h := sha256.New()
|
||||||
ciphertext := make([]byte, aes.BlockSize+len(b))
|
h.Write(data)
|
||||||
|
checksum := h.Sum(nil)
|
||||||
iv := ciphertext[:aes.BlockSize]
|
if len(checksum) != 32 {
|
||||||
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
|
return "", errors.New("wrong cs size")
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ciphertext := make([]byte, 32+len(data))
|
||||||
|
|
||||||
|
iv := make([]byte, aes.BlockSize)
|
||||||
|
_, err = io.ReadFull(rand.Reader, iv)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
combinedData := make([]byte, 0, 32+len(data))
|
||||||
|
combinedData = append(combinedData, checksum...)
|
||||||
|
combinedData = append(combinedData, data...)
|
||||||
|
|
||||||
cfb := cipher.NewCFBEncrypter(block, iv)
|
cfb := cipher.NewCFBEncrypter(block, iv)
|
||||||
cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
|
cfb.XORKeyStream(ciphertext, combinedData)
|
||||||
|
|
||||||
return ciphertext, nil
|
pl := aesPayload{
|
||||||
|
Salt: salt,
|
||||||
|
IV: iv,
|
||||||
|
Data: ciphertext,
|
||||||
|
Version: 1,
|
||||||
|
Rounds: rounds,
|
||||||
|
Algorithm: "AES",
|
||||||
}
|
}
|
||||||
|
|
||||||
func DecryptAESSimple(password, text []byte) ([]byte, error) {
|
jbin, err := json.Marshal(pl)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
key, err := scrypt.Key(password, nil, 32768, 8, 1, 32) // this is not 100% correct, rounds too low and salt is missing
|
res := base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(jbin)
|
||||||
|
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecryptAESSimple(password []byte, encText string) ([]byte, error) {
|
||||||
|
|
||||||
|
jbin, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(encText)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pl aesPayload
|
||||||
|
err = json.Unmarshal(jbin, &pl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := scrypt.Key(password, pl.Salt, pl.Rounds, 8, 1, 32) // this is not 100% correct, rounds too low and salt is missing
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -50,18 +106,24 @@ func DecryptAESSimple(password, text []byte) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(text) < aes.BlockSize {
|
dest := make([]byte, len(pl.Data))
|
||||||
return nil, errors.New("ciphertext too short")
|
|
||||||
|
cfb := cipher.NewCFBDecrypter(block, pl.IV)
|
||||||
|
cfb.XORKeyStream(dest, pl.Data)
|
||||||
|
|
||||||
|
if len(dest) < 32 {
|
||||||
|
return nil, errors.New("payload too small")
|
||||||
}
|
}
|
||||||
|
|
||||||
iv := text[:aes.BlockSize]
|
chck := dest[:32]
|
||||||
text = text[aes.BlockSize:]
|
data := dest[32:]
|
||||||
cfb := cipher.NewCFBDecrypter(block, iv)
|
|
||||||
cfb.XORKeyStream(text, text)
|
|
||||||
|
|
||||||
data, err := base64.StdEncoding.DecodeString(string(text))
|
h := sha256.New()
|
||||||
if err != nil {
|
h.Write(data)
|
||||||
return nil, err
|
chck2 := h.Sum(nil)
|
||||||
|
|
||||||
|
if !bytes.Equal(chck, chck2) {
|
||||||
|
return nil, errors.New("checksum mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package cryptext
|
package cryptext
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestEncryptAESSimple(t *testing.T) {
|
func TestEncryptAESSimple(t *testing.T) {
|
||||||
|
|
||||||
@ -8,15 +11,25 @@ func TestEncryptAESSimple(t *testing.T) {
|
|||||||
|
|
||||||
str1 := []byte("Hello World")
|
str1 := []byte("Hello World")
|
||||||
|
|
||||||
str2, err := EncryptAESSimple(pw, str1)
|
str2, err := EncryptAESSimple(pw, str1, 512)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", str2)
|
||||||
|
|
||||||
str3, err := DecryptAESSimple(pw, str2)
|
str3, err := DecryptAESSimple(pw, str2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEqual(t, string(str1), string(str3))
|
assertEqual(t, string(str1), string(str3))
|
||||||
|
|
||||||
|
str4, err := EncryptAESSimple(pw, str3, 512)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotEqual(t, string(str2), string(str4))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,3 +23,9 @@ func assertEqual(t *testing.T, actual string, expected string) {
|
|||||||
t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected)
|
t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func assertNotEqual(t *testing.T, actual string, expected string) {
|
||||||
|
if actual == expected {
|
||||||
|
t.Errorf("values do not differ: Actual: '%v', Expected: '%v'", actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user