Commit fd9cb0d2 authored by harrylee's avatar harrylee Committed by vipwzw

add storage_test and crypto util

parent 244977d7
package crypto
import (
"crypto/aes"
"crypto/cipher"
)
type AES struct {
key []byte
//iv的长度必须等于block块的大小,这里是16字节,固定
iv []byte
}
//AES 密钥长度为 16,24,32 字节,三种
func NewAES(key, iv []byte) *AES {
return &AES{key: key, iv: iv}
}
func (a *AES) Encrypt(origData []byte) ([]byte, error) {
block, err := aes.NewCipher(a.key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
origData = PKCS5Padding(origData, blockSize)
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, a.iv[:blockSize])
crypted := make([]byte, len(origData))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
func (a *AES) Decrypt(crypted []byte) ([]byte, error) {
block, err := aes.NewCipher(a.key)
if err != nil {
return nil, err
}
blockSize := block.BlockSize()
blockMode := cipher.NewCBCDecrypter(block, a.iv[:blockSize])
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
// origData = ZeroUnPadding(origData)
return origData, nil
}
package crypto
import (
"encoding/base64"
"github.com/stretchr/testify/assert"
"testing"
)
//DES 加解密测试
func TestAes(t *testing.T) {
aes := NewAES(keys[2],ivs[0])
result, err := aes.Encrypt(contents[1])
if err != nil {
t.Error(err)
}
t.Log(base64.StdEncoding.EncodeToString(result))
origData, err := aes.Decrypt(result)
if err != nil {
t.Error(err)
}
assert.Equal(t, contents[1], origData)
}
package crypto
import "bytes"
type Crypto interface {
Encrypt(origData []byte) ([]byte, error)
Decrypt(crypted []byte) ([]byte, error)
}
func ZeroPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{0}, padding)
return append(ciphertext, padtext...)
}
func ZeroUnPadding(origData []byte) []byte {
return bytes.TrimRightFunc(origData, func(r rune) bool {
return r == rune(0)
})
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) []byte {
length := len(origData)
// 去掉最后一个字节 unpadding 次
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
\ No newline at end of file
package crypto
import (
"crypto/cipher"
"crypto/des"
)
type DES struct {
key []byte
//iv的长度必须等于block块的大小
iv []byte
}
func NewDES(key, iv []byte) *DES {
return &DES{key: key, iv: iv}
}
func (d *DES) Encrypt(origData []byte) ([]byte, error) {
block, err := des.NewCipher(d.key)
if err != nil {
return nil, err
}
origData = PKCS5Padding(origData, block.BlockSize())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, d.iv[:block.BlockSize()])
crypted := make([]byte, len(origData))
// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
// crypted := origData
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
// 密钥key长度固定8字节
func (d *DES) Decrypt(crypted []byte) ([]byte, error) {
block, err := des.NewCipher(d.key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, d.iv[:block.BlockSize()])
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
// origData = ZeroUnPadding(origData)
return origData, nil
}
type TripleDES struct {
key []byte
//iv的长度必须等于block块的大小
iv []byte
}
func NewTripleDES(key, iv []byte) *TripleDES {
return &TripleDES{key: key, iv: iv}
}
// 3DES加密 24字节
func (d *TripleDES) Encrypt(origData []byte) ([]byte, error) {
block, err := des.NewTripleDESCipher(d.key)
if err != nil {
return nil, err
}
origData = PKCS5Padding(origData, block.BlockSize())
// origData = ZeroPadding(origData, block.BlockSize())
blockMode := cipher.NewCBCEncrypter(block, d.iv[:block.BlockSize()])
crypted := make([]byte, len(origData))
blockMode.CryptBlocks(crypted, origData)
return crypted, nil
}
// 3DES解密
func (d *TripleDES) Decrypt(crypted []byte) ([]byte, error) {
block, err := des.NewTripleDESCipher(d.key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCBCDecrypter(block, d.iv[:block.BlockSize()])
origData := make([]byte, len(crypted))
// origData := crypted
blockMode.CryptBlocks(origData, crypted)
origData = PKCS5UnPadding(origData)
// origData = ZeroUnPadding(origData)
return origData, nil
}
package crypto
import (
"encoding/base64"
"github.com/stretchr/testify/assert"
"testing"
)
var (
contents = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
keys = [][]byte{
[]byte("123456ab"),
[]byte("G2F4ED5m123456abx6vDrScs"),
[]byte("G2F4ED5m123456abx6vDrScsHD3psX7k"),
}
ivs = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
)
//DES 加解密测试
func TestDes(t *testing.T) {
des := NewDES(keys[0], ivs[0])
result, err := des.Encrypt(contents[0])
if err != nil {
t.Error(err)
}
t.Log(base64.StdEncoding.EncodeToString(result))
origData, err := des.Decrypt(result)
if err != nil {
t.Error(err)
}
assert.Equal(t, contents[0], origData)
}
//3DES 加解密测试
func Test3Des(t *testing.T) {
des := NewTripleDES(keys[1], ivs[1])
result, err := des.Encrypt(contents[0])
if err != nil {
t.Error(err)
}
t.Log(base64.StdEncoding.EncodeToString(result))
origData, err := des.Decrypt(result)
if err != nil {
t.Error(err)
}
assert.Equal(t, contents[0], origData)
}
package executor
import (
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
"math/rand"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/queue"
des "github.com/33cn/plugin/plugin/dapp/storage/crypto"
oty "github.com/33cn/plugin/plugin/dapp/storage/types"
"github.com/stretchr/testify/assert"
"strings"
)
type execEnv struct {
blockTime int64
blockHeight int64
difficulty uint64
}
var (
PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
Nodes = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
contents = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
keys = [][]byte{
[]byte("123456ab"),
[]byte("G2F4ED5m123456abx6vDrScs"),
[]byte("G2F4ED5m123456abx6vDrScsHD3psX7k"),
}
ivs = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
[]byte("1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR"),
[]byte("1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k"),
[]byte("1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs"),
}
)
var (
r *rand.Rand
)
func init() {
r = rand.New(rand.NewSource(types.Now().UnixNano()))
}
func TestOrace(t *testing.T) {
cfg := types.NewChain33Config(strings.Replace(types.GetDefaultCfgstring(), "Title=\"local\"", "Title=\"chain33\"", 1))
Init(oty.StorageX, cfg, nil)
total := 100 * types.Coin
accountA := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[0]),
}
accountB := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[1]),
}
accountC := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[2]),
}
accountD := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[3]),
}
execAddr := address.ExecAddress(oty.StorageX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 1000)
_, _, kvdb := util.CreateTestDB()
accA, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
accA.SaveExecAccount(execAddr, &accountA)
accB, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
accB.SaveExecAccount(execAddr, &accountB)
accC, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
accC.SaveExecAccount(execAddr, &accountC)
accD, _ := account.NewAccountDB(cfg, "coins", "bty", stateDB)
accD.SaveExecAccount(execAddr, &accountD)
env := execEnv{
10,
cfg.GetDappFork(oty.StorageX, "Enable"),
1539918074,
}
// publish event
ety := types.LoadExecutorType(oty.StorageX)
tx, err := ety.Create("ContentStorage", &oty.ContentOnlyNotaryStorage{Content: contents[0]})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, oty.StorageX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyA)
assert.Nil(t, err)
t.Log("tx", tx)
exec := newStorage()
q := queue.New("channel")
q.SetConfig(cfg)
api, _ := client.New(q.Client(), nil)
exec.SetAPI(api)
exec.SetStateDB(stateDB)
exec.SetLocalDB(kvdb)
exec.SetEnv(1, env.blockTime, env.difficulty)
receipt, err := exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptDate := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(tx, receiptDate, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
var txhash string
txhash = common.ToHex(tx.Hash())
t.Log("txhash:", txhash)
//根据hash查询存储得明文内容
msg, err := exec.Query(oty.FuncNameQueryStorage, types.Encode(&oty.QueryStorage{
TxHash: txhash}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply := msg.(*oty.Storage)
assert.Equal(t, contents[0], reply.GetContentStorage().Content)
//根据hash批量查询存储数据
msg, err = exec.Query(oty.FuncNameBatchQueryStorage, types.Encode(&oty.BatchQueryStorage{
TxHashs: []string{txhash}}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply2 := msg.(*oty.BatchReplyStorage)
assert.Equal(t, contents[0], reply2.Storages[0].GetContentStorage().Content)
tx, err = ety.Create("HashStorage", &oty.HashOnlyNotaryStorage{Hash: common.Sha256(contents[0])})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, oty.StorageX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyA)
assert.Nil(t, err)
t.Log("tx", tx)
exec.SetEnv(env.blockHeight+1, env.blockTime+20, env.difficulty+1)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptDate = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx, receiptDate, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
txhash = common.ToHex(tx.Hash())
t.Log("txhash:", txhash)
//根据hash查询存储得明文内容
msg, err = exec.Query(oty.FuncNameQueryStorage, types.Encode(&oty.QueryStorage{
TxHash: txhash}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*oty.Storage)
assert.Equal(t, common.Sha256(contents[0]), reply.GetHashStorage().Hash)
//根据hash批量查询存储数据
msg, err = exec.Query(oty.FuncNameBatchQueryStorage, types.Encode(&oty.BatchQueryStorage{
TxHashs: []string{txhash}}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply2 = msg.(*oty.BatchReplyStorage)
assert.Equal(t, common.Sha256(contents[0]), reply2.Storages[0].GetHashStorage().Hash)
//存储链接地址
tx, err = ety.Create("LinkStorage", &oty.LinkNotaryStorage{Hash: common.Sha256(contents[0]), Link: contents[0]})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, oty.StorageX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyA)
assert.Nil(t, err)
t.Log("tx", tx)
exec.SetEnv(env.blockHeight+1, env.blockTime+20, env.difficulty+1)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptDate = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx, receiptDate, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
txhash = common.ToHex(tx.Hash())
t.Log("txhash:", txhash)
//根据hash查询存储得明文内容
msg, err = exec.Query(oty.FuncNameQueryStorage, types.Encode(&oty.QueryStorage{
TxHash: txhash}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*oty.Storage)
assert.Equal(t, common.Sha256(contents[0]), reply.GetLinkStorage().Hash)
//根据hash批量查询存储数据
msg, err = exec.Query(oty.FuncNameBatchQueryStorage, types.Encode(&oty.BatchQueryStorage{
TxHashs: []string{txhash}}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply2 = msg.(*oty.BatchReplyStorage)
assert.Equal(t, common.Sha256(contents[0]), reply2.Storages[0].GetLinkStorage().Hash)
//加密存储
aes := des.NewAES(keys[2], ivs[0])
crypted, err := aes.Encrypt(contents[0])
if err != nil {
t.Error(err)
}
tx, err = ety.Create("EncryptStorage", &oty.EncryptNotaryStorage{ContentHash: common.Sha256(contents[0]), EncryptContent: crypted, Nonce: ivs[0]})
assert.Nil(t, err)
tx, err = types.FormatTx(cfg, oty.StorageX, tx)
assert.Nil(t, err)
tx, err = signTx(tx, PrivKeyA)
assert.Nil(t, err)
t.Log("tx", tx)
exec.SetEnv(env.blockHeight+1, env.blockTime+20, env.difficulty+1)
receipt, err = exec.Exec(tx, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range receipt.KV {
stateDB.Set(kv.Key, kv.Value)
}
receiptDate = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx, receiptDate, int(1))
if err != nil {
t.Error(err)
}
for _, kv := range set.KV {
kvdb.Set(kv.Key, kv.Value)
}
txhash = common.ToHex(tx.Hash())
t.Log("txhash:", txhash)
//根据hash查询存储得明文内容
msg, err = exec.Query(oty.FuncNameQueryStorage, types.Encode(&oty.QueryStorage{
TxHash: txhash}))
if err != nil {
t.Error(err)
}
t.Log(msg)
reply = msg.(*oty.Storage)
assert.Equal(t, common.Sha256(contents[0]), reply.GetEncryptStorage().ContentHash)
assert.Equal(t, crypted, reply.GetEncryptStorage().EncryptContent)
assert.Equal(t, ivs[0], reply.GetEncryptStorage().Nonce)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(oty.StorageX, signType))
if err != nil {
return tx, err
}
bytes, err := common.FromHex(hexPrivKey[:])
if err != nil {
return tx, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
if err != nil {
return tx, err
}
tx.Sign(int32(signType), privKey)
return tx, nil
}
//// golang中标准对称加密库测试
//func TestCryptoDES(t *testing.T){
// key := []byte("123456")
// result,err
// des.NewCipher()
//}
//// golang中AES加密库测试
//func TestCryptoAES(t *testing.T){
//
//}
......@@ -61,7 +61,7 @@ message EncryptContentOnlyNotaryStorage {
bytes nonce = 2;
}
// 分享隐私存证模型
// 分享隐私存证模型,需要完备的sdk或者相应的密钥库支持
message EncryptShareNotaryStorage {
//存证明文内容的hash值,推荐使用sha256哈希,限制256位得摘要值
bytes contentHash = 1;
......
......@@ -14,28 +14,31 @@ import (
// action类型id和name,这些常量可以自定义修改
const (
TyUnknowAction = iota + 100
TyUnknowAction = iota
TyContentStorageAction
TyHashStorageAction
TyLinkStorageAction
TyEncryptStorageAction
TyEncryShareStorageAction
TyEncryptShareStorageAction
NameContentStorageAction = "ContentStorage"
NameHashStorageAction = "HashStorage"
NameLinkStorageAction = "LinkStorage"
NameEncryptStorageAction = "EncryptStorage"
NameEncryShareStorageAction = "EncryShareStorage"
NameEncryptShareStorageAction = "EncryptShareStorage"
FuncNameQueryStorage = "QueryStorage"
FuncNameBatchQueryStorage = "BatchQueryStorage"
)
// log类型id值
const (
TyUnknownLog = iota + 100
TyUnknownLog = iota
TyContentStorageLog
TyHashStorageLog
TyLinkStorageLog
TyEncryptStorageLog
TyEncryShareStorageLog
TyEncryptShareStorageLog
)
var (
......@@ -47,7 +50,7 @@ var (
NameHashStorageAction: TyHashStorageAction,
NameLinkStorageAction: TyLinkStorageAction,
NameEncryptStorageAction: TyEncryptStorageAction,
NameEncryShareStorageAction: TyEncryShareStorageAction,
NameEncryptShareStorageAction: TyEncryptShareStorageAction,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = map[int64]*types.LogInfo{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment