Fix implementation, tests, and implement go modules
This commit is contained in:
parent
251c6c0092
commit
a381f5b298
|
@ -10,3 +10,6 @@
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
|
|
||||||
|
# Jetbrains
|
||||||
|
.idea/
|
||||||
|
|
66
compute.go
66
compute.go
|
@ -8,9 +8,12 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
"time"
|
"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) {
|
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
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
cipherText := make([]byte, len(plainText))
|
cipherText := make([]byte, len(plainText))
|
||||||
//iv := make([]byte, aes.BlockSize)
|
// iv := make([]byte, aes.BlockSize)
|
||||||
|
|
||||||
stream := cipher.NewCTR(block, iv[:aes.BlockSize])
|
stream := cipher.NewCTR(block, iv[:aes.BlockSize])
|
||||||
stream.XORKeyStream(cipherText, plainText)
|
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) {
|
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)
|
dataHash, _ := obj.hash(encryptedBytes)
|
||||||
timeHash, _ := obj.hash(timeBytes)
|
timeHash, _ := obj.hash(timeBytes)
|
||||||
pubkeyHash, _ := obj.hash(pubkeyBytes[:65])
|
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], userHash)
|
||||||
copy(full[32:64], pubkeyHash)
|
copy(full[32:64], pubkeyHash)
|
||||||
copy(full[64:96], timeHash)
|
copy(full[64:96], timeHash)
|
||||||
copy(full[96:128], dataHash)
|
copy(full[96:128], dataHash)
|
||||||
fullHash, _ = obj.hash(full[:128])
|
fullHash, _ = obj.hash(full[:128])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +66,11 @@ func (obj *SecureJson) checkInputOutputJson(inputJson []byte, outputJson []byte)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ji.PublicKey != jo.PublicKey {
|
if ji.PublicKey != jo.PublicKey {
|
||||||
err = errors.New("Check fail for PublicKey")
|
err = errors.New("check failed for PublicKey")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if obj.convertFromStringToInt64(ji.Timestamp) < obj.convertFromStringToInt64(jo.Timestamp) {
|
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
|
return
|
||||||
}
|
}
|
||||||
ok = true
|
ok = true
|
||||||
|
@ -101,14 +104,14 @@ func (obj *SecureJson) putJsonToStorage(inputJson []byte) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) convertFromStringToInt64(timeStr string) (timestamp int64) {
|
func (obj *SecureJson) convertFromStringToInt64(timeStr string) (timestamp int64) {
|
||||||
fmt.Sscanf(timeStr, "%x", ×tamp)
|
_, _ = fmt.Sscanf(timeStr, "%x", ×tamp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) checkTimestampBeforeNow(timeStr string) (ok bool) {
|
func (obj *SecureJson) checkTimestampBeforeNow(timeStr string) (ok bool) {
|
||||||
timestamp := obj.convertFromStringToInt64(timeStr)
|
timestamp := obj.convertFromStringToInt64(timeStr)
|
||||||
timenow := time.Now().UnixNano()
|
timenow := time.Now().UnixNano()
|
||||||
return (timenow > timestamp)
|
return timenow > timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) bytesToString(msg []byte) string {
|
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 {
|
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 {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
signature, err := btcec.ParseSignature(sig, btcec.S256())
|
signature, err := ecdsa.ParseSignature(sig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
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) {
|
func (obj *SecureJson) sign(msg []byte, privKey []byte) ([]byte, error) {
|
||||||
priv, _ := btcec.PrivKeyFromBytes(btcec.S256(), privKey)
|
priv, _ := btcec.PrivKeyFromBytes(privKey)
|
||||||
sig, err := priv.Sign(msg)
|
sig, err := priv.ToECDSA().Sign(entropy.GetOptimizedRand(), msg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
return sig.Serialize(), err
|
return sig, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) getPubKey(privKey []byte) ([]byte, error) {
|
func (obj *SecureJson) getPubKey(privKey []byte) ([]byte, error) {
|
||||||
pubKey := make([]byte, 65)
|
pubKey := make([]byte, 65)
|
||||||
_, pub := btcec.PrivKeyFromBytes(btcec.S256(), privKey)
|
_, pub := btcec.PrivKeyFromBytes(privKey)
|
||||||
pubKey = pub.SerializeUncompressed()
|
pubKey = pub.SerializeUncompressed()
|
||||||
return pubKey, nil
|
return pubKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) getTimestamp() ([]byte, error) {
|
func (obj *SecureJson) getTimestamp() ([]byte, error) {
|
||||||
timeNowBytes := make([]byte, 8)
|
timeNowBytes := make([]byte, 8)
|
||||||
timeNowStr := fmt.Sprintf("%x", time.Now().Unix())
|
timeNowStr := fmt.Sprintf("%x", time.Now().Unix())
|
||||||
timeNowBytes, err := hex.DecodeString(timeNowStr)
|
timeNowBytes, err := hex.DecodeString(timeNowStr)
|
||||||
return timeNowBytes, err
|
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)
|
return obj.shake256(data, 32)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (obj *SecureJson) genIv(userName string) ([]byte, error) {
|
func (obj *SecureJson) genIv(userName string) ([]byte, error) {
|
||||||
return obj.shake256([]byte(userName), 16)
|
return obj.shake256([]byte(userName), 16)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
|
@ -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=
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StubStorage struct {
|
type StubStorage struct {
|
||||||
|
@ -12,7 +13,7 @@ type StubStorage struct {
|
||||||
|
|
||||||
func (obj *StubStorage) Put(key string, value []byte) error {
|
func (obj *StubStorage) Put(key string, value []byte) error {
|
||||||
obj.jsonBytes = value
|
obj.jsonBytes = value
|
||||||
//fmt.Println("Put", string(obj.jsonBytes))
|
fmt.Println("Put", string(obj.jsonBytes))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,43 +21,42 @@ func (obj *StubStorage) Get(key string) ([]byte, error) {
|
||||||
if len(obj.jsonBytes) == 0 {
|
if len(obj.jsonBytes) == 0 {
|
||||||
return []byte{}, errors.New("Empty")
|
return []byte{}, errors.New("Empty")
|
||||||
}
|
}
|
||||||
//fmt.Println("Get", string(obj.jsonBytes))
|
fmt.Println("Get", string(obj.jsonBytes))
|
||||||
return obj.jsonBytes, nil
|
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)
|
ok, err := obj.VerifyJson(jsonBytes)
|
||||||
if err != nil || !ok {
|
if err != nil || !ok {
|
||||||
fmt.Println(err)
|
t.Errorf("%s: VerifyJson failed: %s", logPrefix, err)
|
||||||
fmt.Println(logprifix, "Verify the Json Fail")
|
|
||||||
}
|
}
|
||||||
var data Json
|
var data Json
|
||||||
err = json.Unmarshal(jsonBytes, &data)
|
err = json.Unmarshal(jsonBytes, &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(logprifix, "Json Unmarshal Fail")
|
t.Errorf("%s: Unmarshal failed: %s", logPrefix, err)
|
||||||
}
|
}
|
||||||
passwd, _ := obj.hash([]byte("1234"))
|
passwd, _ := obj.hash([]byte("1234"))
|
||||||
plain, err := obj.Decrypt(data.EncryptedData, data.UserName, passwd)
|
plain, err := obj.Decrypt(data.EncryptedData, data.UserName, passwd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(logprifix, "Decrypt Fail")
|
t.Errorf("%s: Decrypt failed: %s", logPrefix, err)
|
||||||
}
|
}
|
||||||
if string(plain) != "MyData" {
|
if plain != "MyData" {
|
||||||
fmt.Println(logprifix, "Decrypted data Fail")
|
t.Errorf("%s: Decrypt failed: %s", logPrefix, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleNew() {
|
func TestNew(t *testing.T) {
|
||||||
storage := new(StubStorage)
|
storage := new(StubStorage)
|
||||||
obj := New(storage)
|
obj := New(storage)
|
||||||
jsonBytes := []byte(`{"UserName":"MyUser","Signature":"MEUCIDJmafX+XGJV+Ws2jz0lF2YdJLcrEXAw1ZBPB0/+KjJyAiEA1CR3f/pbngSl0P0mqb7McKSbveSsQ1ir5L4ulpKamuw=","EncryptedData":"F4Zw1vYy","Timestamp":"W5D07g==","PublicKey":"BCNhwc+1nmUYLSDJnacQaKQB1YyT26gdwHCZZd1iwsB14rfGvwv9fuAHjyln9Alap2Voxp/rrdiU2QvE8HuMt5s="}`)
|
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")
|
jsonBytes, err := obj.GenerateJson("MyUser", "1234", "MyData")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
testJson(jsonBytes, "Generated", obj)
|
testJson(jsonBytes, "Generated", obj, t)
|
||||||
|
|
||||||
_, err = obj.GetJson(jsonBytes)
|
_, err = obj.GetJson(jsonBytes)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Println("Expecting error when no value stored")
|
fmt.Println("Expecting error when no value stored")
|
||||||
|
@ -69,8 +69,8 @@ func ExampleNew() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Get Json Fail")
|
fmt.Println("Get Json Fail")
|
||||||
}
|
}
|
||||||
testJson(jsonBytes, "Get", obj)
|
testJson(jsonBytes, "Get", obj, t)
|
||||||
fmt.Println(true)
|
fmt.Println(true)
|
||||||
//output:
|
// output:
|
||||||
//true
|
// true
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue