From a381f5b2980d008a6a9c8f5229333577df5606f2 Mon Sep 17 00:00:00 2001 From: "kayos@tcp.direct" Date: Sat, 9 Jul 2022 10:16:08 -0700 Subject: [PATCH] Fix implementation, tests, and implement go modules --- .gitignore | 3 +++ compute.go | 66 +++++++++++++++++++++++++--------------------- go.mod | 15 +++++++++++ go.sum | 16 +++++++++++ securejson_test.go | 32 +++++++++++----------- 5 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 go.mod create mode 100644 go.sum diff --git a/.gitignore b/.gitignore index f1c181e..0961cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out + +# Jetbrains +.idea/ diff --git a/compute.go b/compute.go index 3b92209..3007023 100644 --- a/compute.go +++ b/compute.go @@ -8,9 +8,12 @@ import ( "encoding/json" "errors" "fmt" - "github.com/btcsuite/btcd/btcec" - "golang.org/x/crypto/sha3" "time" + + "git.tcp.direct/kayos/common/entropy" + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "golang.org/x/crypto/sha3" ) func (obj *SecureJson) encrypt(plainText []byte, iv []byte, key []byte) ([]byte, error) { @@ -23,7 +26,7 @@ func (obj *SecureJson) encrypt(plainText []byte, iv []byte, key []byte) ([]byte, return []byte{}, err } cipherText := make([]byte, len(plainText)) - //iv := make([]byte, aes.BlockSize) + // iv := make([]byte, aes.BlockSize) stream := cipher.NewCTR(block, iv[:aes.BlockSize]) stream.XORKeyStream(cipherText, plainText) @@ -31,7 +34,7 @@ func (obj *SecureJson) encrypt(plainText []byte, iv []byte, key []byte) ([]byte, } func (obj *SecureJson) genHash(userBytes []byte, encryptedBytes []byte, timeBytes []byte, pubkeyBytes []byte) (fullHash []byte) { - userHash, _ := obj.hash(userBytes) + userHash, _ := obj.hash(userBytes) dataHash, _ := obj.hash(encryptedBytes) timeHash, _ := obj.hash(timeBytes) pubkeyHash, _ := obj.hash(pubkeyBytes[:65]) @@ -40,8 +43,8 @@ func (obj *SecureJson) genHash(userBytes []byte, encryptedBytes []byte, timeByte copy(full[:32], userHash) copy(full[32:64], pubkeyHash) copy(full[64:96], timeHash) - copy(full[96:128], dataHash) - fullHash, _ = obj.hash(full[:128]) + copy(full[96:128], dataHash) + fullHash, _ = obj.hash(full[:128]) return } @@ -63,11 +66,11 @@ func (obj *SecureJson) checkInputOutputJson(inputJson []byte, outputJson []byte) return } if ji.PublicKey != jo.PublicKey { - err = errors.New("Check fail for PublicKey") + err = errors.New("check failed for PublicKey") return } if obj.convertFromStringToInt64(ji.Timestamp) < obj.convertFromStringToInt64(jo.Timestamp) { - err = errors.New("Check fail for Timestamp. Input timestamp must be greater then the ouput one.") + err = errors.New("input timestamp must be greater then the ouput one") return } ok = true @@ -101,14 +104,14 @@ func (obj *SecureJson) putJsonToStorage(inputJson []byte) (err error) { } func (obj *SecureJson) convertFromStringToInt64(timeStr string) (timestamp int64) { - fmt.Sscanf(timeStr, "%x", ×tamp) + _, _ = fmt.Sscanf(timeStr, "%x", ×tamp) return } func (obj *SecureJson) checkTimestampBeforeNow(timeStr string) (ok bool) { timestamp := obj.convertFromStringToInt64(timeStr) timenow := time.Now().UnixNano() - return (timenow > timestamp) + return timenow > timestamp } func (obj *SecureJson) bytesToString(msg []byte) string { @@ -125,11 +128,11 @@ func (obj *SecureJson) stringToBytes(msg string) (res []byte) { } func (obj *SecureJson) verify(msg []byte, pub []byte, sig []byte) bool { - pubKey, err := btcec.ParsePubKey(pub, btcec.S256()) + pubKey, err := btcec.ParsePubKey(pub) if err != nil { return false } - signature, err := btcec.ParseSignature(sig, btcec.S256()) + signature, err := ecdsa.ParseSignature(sig) if err != nil { return false } @@ -137,40 +140,43 @@ func (obj *SecureJson) verify(msg []byte, pub []byte, sig []byte) bool { } func (obj *SecureJson) sign(msg []byte, privKey []byte) ([]byte, error) { - priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKey) - sig, err := priv.Sign(msg) + priv, _ := btcec.PrivKeyFromBytes(privKey) + sig, err := priv.ToECDSA().Sign(entropy.GetOptimizedRand(), msg, nil) if err != nil { return []byte{}, err } - return sig.Serialize(), err + return sig, err } func (obj *SecureJson) getPubKey(privKey []byte) ([]byte, error) { pubKey := make([]byte, 65) - _, pub := btcec.PrivKeyFromBytes(btcec.S256(), privKey) + _, pub := btcec.PrivKeyFromBytes(privKey) pubKey = pub.SerializeUncompressed() return pubKey, nil } func (obj *SecureJson) getTimestamp() ([]byte, error) { timeNowBytes := make([]byte, 8) - timeNowStr := fmt.Sprintf("%x", time.Now().Unix()) + timeNowStr := fmt.Sprintf("%x", time.Now().Unix()) timeNowBytes, err := hex.DecodeString(timeNowStr) return timeNowBytes, err } - -func (obj *SecureJson) shake256(data []byte, length int) ([]byte, error) { - sum := make([]byte, length) - hashObj := sha3.NewShake256() - hashObj.Write(data) - hashObj.Read(sum) - return sum, nil -} -func (obj *SecureJson) hash(data []byte) ([]byte, error) { +func (obj *SecureJson) shake256(data []byte, length int) ([]byte, error) { + sum := make([]byte, length) + hashObj := sha3.NewShake256() + _, writeErr := hashObj.Write(data) + if writeErr != nil { + return sum, writeErr + } + _, readErr := hashObj.Read(sum) + return sum, readErr +} + +func (obj *SecureJson) hash(data []byte) ([]byte, error) { return obj.shake256(data, 32) } - -func (obj *SecureJson) genIv(userName string) ([]byte, error) { - return obj.shake256([]byte(userName), 16) -} \ No newline at end of file + +func (obj *SecureJson) genIv(userName string) ([]byte, error) { + return obj.shake256([]byte(userName), 16) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..402d581 --- /dev/null +++ b/go.mod @@ -0,0 +1,15 @@ +module securejson + +go 1.18 + +require ( + git.tcp.direct/kayos/common v0.5.6-0.20220708105112-d07f8de10512 + github.com/btcsuite/btcd/btcec/v2 v2.2.0 + golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d +) + +require ( + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect + nullprogram.com/x/rng v1.1.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..779a02c --- /dev/null +++ b/go.sum @@ -0,0 +1,16 @@ +git.tcp.direct/kayos/common v0.5.6-0.20220708105112-d07f8de10512 h1:2Ti+OV+z5ld7Ivb2TmmLPTK7+KxgjlnGY1Md6b2QnMs= +git.tcp.direct/kayos/common v0.5.6-0.20220708105112-d07f8de10512/go.mod h1:jG1yXbN+5PrRZwGe32qIGWgLC4x5JWdyNBbMj1gIWB0= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +nullprogram.com/x/rng v1.1.0 h1:SMU7DHaQSWtKJNTpNFIFt8Wd/KSmOuSDPXrMFp/UMro= +nullprogram.com/x/rng v1.1.0/go.mod h1:glGw6V87vyfawxCzqOABL3WfL95G65az9Z2JZCylCkg= diff --git a/securejson_test.go b/securejson_test.go index 3f9f130..208c372 100644 --- a/securejson_test.go +++ b/securejson_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "testing" ) type StubStorage struct { @@ -12,7 +13,7 @@ type StubStorage struct { func (obj *StubStorage) Put(key string, value []byte) error { obj.jsonBytes = value - //fmt.Println("Put", string(obj.jsonBytes)) + fmt.Println("Put", string(obj.jsonBytes)) return nil } @@ -20,43 +21,42 @@ func (obj *StubStorage) Get(key string) ([]byte, error) { if len(obj.jsonBytes) == 0 { return []byte{}, errors.New("Empty") } - //fmt.Println("Get", string(obj.jsonBytes)) + fmt.Println("Get", string(obj.jsonBytes)) return obj.jsonBytes, nil } -func testJson(jsonBytes []byte, logprifix string, obj *SecureJson) { +func testJson(jsonBytes []byte, logPrefix string, obj *SecureJson, t *testing.T) { ok, err := obj.VerifyJson(jsonBytes) if err != nil || !ok { - fmt.Println(err) - fmt.Println(logprifix, "Verify the Json Fail") + t.Errorf("%s: VerifyJson failed: %s", logPrefix, err) } var data Json err = json.Unmarshal(jsonBytes, &data) if err != nil { - fmt.Println(logprifix, "Json Unmarshal Fail") + t.Errorf("%s: Unmarshal failed: %s", logPrefix, err) } passwd, _ := obj.hash([]byte("1234")) plain, err := obj.Decrypt(data.EncryptedData, data.UserName, passwd) if err != nil { - fmt.Println(logprifix, "Decrypt Fail") + t.Errorf("%s: Decrypt failed: %s", logPrefix, err) } - if string(plain) != "MyData" { - fmt.Println(logprifix, "Decrypted data Fail") + if plain != "MyData" { + t.Errorf("%s: Decrypt failed: %s", logPrefix, err) } } -func ExampleNew() { +func TestNew(t *testing.T) { storage := new(StubStorage) obj := New(storage) jsonBytes := []byte(`{"UserName":"MyUser","Signature":"MEUCIDJmafX+XGJV+Ws2jz0lF2YdJLcrEXAw1ZBPB0/+KjJyAiEA1CR3f/pbngSl0P0mqb7McKSbveSsQ1ir5L4ulpKamuw=","EncryptedData":"F4Zw1vYy","Timestamp":"W5D07g==","PublicKey":"BCNhwc+1nmUYLSDJnacQaKQB1YyT26gdwHCZZd1iwsB14rfGvwv9fuAHjyln9Alap2Voxp/rrdiU2QvE8HuMt5s="}`) - testJson(jsonBytes, "Hardcoded", obj) + testJson(jsonBytes, "Hardcoded", obj, t) jsonBytes, err := obj.GenerateJson("MyUser", "1234", "MyData") if err != nil { panic(err) } - testJson(jsonBytes, "Generated", obj) - + testJson(jsonBytes, "Generated", obj, t) + _, err = obj.GetJson(jsonBytes) if err == nil { fmt.Println("Expecting error when no value stored") @@ -69,8 +69,8 @@ func ExampleNew() { if err != nil { fmt.Println("Get Json Fail") } - testJson(jsonBytes, "Get", obj) + testJson(jsonBytes, "Get", obj, t) fmt.Println(true) - //output: - //true + // output: + // true }