首页>>资讯>>产业

DappLink 一键发钱包之深入理解签名机底层实现机制

2024-11-19 16:39:41 13

一. 签名机概述


    签名机,在 Web3 行业通常指的是用于交易签名的软件服务与硬件设备。数字签名是通过使用私钥对数据进行加密,以确保数据的完整性、来源的真实性以及不可否认性。签名机可以帮助提高密钥的安全性,防止密钥泄露,并且确保签名操作在隔离的环境中进行。  

 

1、签名机的基本功能


私钥管理: 签名机能够存储私钥并确保私钥的安全性。私钥不会离开签名机,所有的签名操作都在硬件中完成,不会暴露到外部环境中。


签名操作: 用户将待签名的数据传递给签名机,签名机使用内部的私钥对数据进行签名,生成签名数据,并将签名返回给用户。


安全隔离: 签名机在物理或逻辑上将私钥与主机系统隔离,防止私钥被泄露或盗用。常见的硬件签名设备包括硬件安全模块(HSM)、USB加密狗、智能卡和 TEE 等。


支持多种签名算法: 常见的数字签名算法包括 ECDSA(椭圆曲线数字签名算法)、EdDSA(Edwards曲线数字签名算法)、RSA等。签名机通常支持多种签名算法,以适应不同的应用需求。


身份认证与授权: 签名机可以作为身份验证的一部分,通过数字签名验证用户或设备的身份。这对于金融交易、加密货币支付等应用非常重要。


2、常见的签名机类型


硬件安全模块(HSM):HSM 是一种物理设备,设计用于保护和管理数字密钥。它为签名操作提供专用的硬件加速,确保私钥的安全性和计算的高效性。常用于金融、企业级应用等需要高安全性的场景。


USB 加密狗(Token:USB加密狗是常见的轻量级签名设备,通常用于身份验证和数字签名。它通过 USB 接口与计算机连接,内部存储密钥并通过加密算法进行签名。


智能卡(Smart Card): 智能卡是一种内置芯片的卡片,通常用于身份验证、银行支付、个人数字证书等场景。与USB加密狗类似,智能卡也通过物理接口进行连接和签名。


移动设备签名机: 一些移动设备(如手机、平板等)也可以作为签名机,通过使用专门的硬件模块(如TPM、Secure Enclave等)提供数字签名服务。移动签名机在支付、身份认证等场景中得到广泛应用。


软件签名机: 在某些场景下,签名操作可以通过软件模拟完成,但这通常不如硬件设备安全。软件签名机依赖计算机的操作系统和软件安全性,适用于较低安全需求的应用场景。


3、签名机的应用领域


加密货币: 在加密货币领域,签名机用于保护钱包的私钥,确保用户在发起交易时能够安全地进行签名,而不暴露私钥。


电子支付: 签名机用于保护支付交易中的私钥,确保交易的安全性和有效性。金融机构和支付平台往往使用HSM等硬件设备来签名交易信息。


身份验证与授权: 签名机广泛应用于身份验证中,通过签名操作确保用户的身份。常见应用包括银行在线服务、电子政务、数字证书签发等。


法律文件签署: 在数字化合同和电子签名的场景中,签名机用于确保签署的文件具有法律效力。签名机能够确保文件未被篡改,并且签署者的身份可以验证。


区块链与智能合约: 在区块链应用中,签名机用于生成和管理与智能合约相关的签名,确保智能合约的执行是由合法用户发起的。


二. 签名机架构设计

4.png

HSM: 支持 CloudHSM 的签名方式

SSM:软签名,签名机部署在 TEE 环境

RPC Services: RPC 接口层,签名机密钥生成,签名相关的接口封装


三. 功能模块


1、Keygen过程

4.png

2、交易签名流程

4.png

四. 核心源码解析


1、Protobuf接口定义


syntax = "proto3";


option go_package = "./protobuf/wallet";

package dapplink.wallet;


message PublicKey {

    string compress_pubkey = 1;

    string decompress_pubkey = 2;

}


message SupportSignWayRequest{

  string consumer_token = 1;

  string type = 2;

}


message SupportSignWayResponse {

  string code = 1;

  string msg = 2;

  bool support = 3;

}


message ExportPublicKeyRequest {

  string consumer_token = 1;

  string type = 2;

  uint64 number = 3;

}


message ExportPublicKeyResponse {

  string code = 1;

  string msg = 2;

  repeated PublicKey public_key = 3;

}


message SignTxMessageRequest {

  string consumer_token = 1;

  string type = 2;

  string public_key = 3;

  string message_hash = 4;

}


message SignTxMessageResponse {

  string code = 1;

  string msg = 2;

  string signature = 3;

}


service WalletService {

  rpc getSupportSignWay(SupportSignWayRequest) returns (SupportSignWayResponse) {}

  rpc exportPublicKeyList(ExportPublicKeyRequest) returns (ExportPublicKeyResponse) {}

  rpc signTxMessage(SignTxMessageRequest) returns (SignTxMessageResponse) {}

}


1. 代码详解



1.1 文件结构


语法声明: syntax = "proto3"; 选择了 proto3,表示使用 Protocol Buffers 第三版。


选项声明: option go_package = "./protobuf/wallet"; 指定 Go 包路径为 ./protobuf/wallet,方便生成的代码直接用在指定目录。


包名: package dapplink.wallet; 定义了 Protocol Buffers 文件的包名为 dapplink.wallet,用于避免命名冲突。


1.2 消息类型解析


message PublicKey {

    string compress_pubkey = 1;

    string decompress_pubkey = 2;

}


作用:用于存储公钥信息。


字段解析:


compress_pubkey: 压缩形式的公钥,类型为 string。


decompress_pubkey: 解压缩形式的公钥,类型为 string。


1.3 SupportSignWayRequest


message SupportSignWayRequest {

  string consumer_token = 1;

  string type = 2;

}


作用:查询支持的签名方式的请求结构。

字段解析:


consumer_token: 表示消费者的身份令牌,用于认证。type: 查询的签名方式类型,具体值取决于业务需求。


1.4 SupportSignWayResponse


message SupportSignWayResponse {

  string code = 1;

  string msg = 2;

  bool support = 3;

}


作用:查询支持签名方式的响应结构。

字段解析:


code:状态码,用于指示请求处理结果。

msg: 描述状态码的消息。

support: 是否支持指定的签名方式,布尔值。


1.5 ExportPublicKeyRequest

message ExportPublicKeyRequest {

  string consumer_token = 1;

  string type = 2;

  uint64 number = 3;

}


作用:导出公钥列表的请求结构。

字段解析:


consumer_token: 消费者令牌。 


type: 公钥类型。


number: 导出的公钥数量,类型为无符号 64 位整数。


1.6 ExportPublicKeyResponse


message ExportPublicKeyResponse {

  string code = 1;

  string msg = 2;

  repeated PublicKey public_key = 3;

}


作用:导出公钥列表的响应结构。


字段解析:


code:状态码。

msg:响应信息。

public_key: 公钥列表,PublicKey类型的数组。


1.7 SignTxMessageRequest


message SignTxMessageRequest {

  string consumer_token = 1;

  string type = 2;

  string public_key = 3;

  string message_hash = 4;

}


作用:请求对交易消息进行签名。


字段解析:


consumer_token: 消费者令牌。


type: 签名方式。


public_key: 用于签名的公钥。


message_hash: 待签名的消息哈希值。


1.8 SignTxMessageResponse

message SignTxMessageResponse {

  string code = 1;

  string msg = 2;

  string signature = 3;

}


作用:签名响应。


字段解析:


code:状态码。

msg:响应消息。

signature:签名结果。


1.9 服务定义


service WalletService {

  rpc getSupportSignWay(SupportSignWayRequest) returns (SupportSignWayResponse) {}

  rpc exportPublicKeyList(ExportPublicKeyRequest) returns (ExportPublicKeyResponse) {}

  rpc signTxMessage(SignTxMessageRequest) returns (SignTxMessageResponse) {}

}

WalletService 定义了钱包服务的接口,包括以下三个 RPC方法:


getSupportSignWay: 

输入: SupportSignWayRequest 

输出: SupportSignWayResponse 

功能: 查询是否支持指定的签名方式。


exportPublicKeyList: 

输入: ExportPublicKeyRequest 

输出: ExportPublicKeyResponse 

功能: 导出指定类型和数量的公钥。


signTxMessage: 

输入: SignTxMessageRequest

输出: SignTxMessageResponse 

功能: 对交易消息进行签名


2. 总结


该 Protocol Buffers 定义文件旨在为一个钱包服务定义结构化数据类型和接口,涵盖了:

1)公钥管理(查询、导出)。

2)签名方式的支持性查询。

3)交易消息签名服务。


通过上述定义,可以生成对应的 Go 代码并实现服务逻辑。


2、RPC服务接口


1. 服务实现


package rpc


import (

    "context"

    "fmt"

    "github.com/dapplink-labs/wallet-sign-go/hsm"

    "net"

    "sync/atomic"


    "google.golang.org/grpc"

    "google.golang.org/grpc/reflection"


    "github.com/ethereum/go-ethereum/log"


    "github.com/dapplink-labs/wallet-sign-go/leveldb"

    "github.com/dapplink-labs/wallet-sign-go/protobuf/wallet"

)


const MaxRecvMessageSize = 1024 * 1024 * 30000


type RpcServerConfig struct {

    GrpcHostname string

    GrpcPort     int

    KeyPath      string

    KeyName      string

    HsmEnable    bool

}


type RpcServer struct {

    *RpcServerConfig

    db        *leveldb.Keys

    HsmClient *hsm.HsmClient


    wallet.UnimplementedWalletServiceServer

    stopped atomic.Bool

}


func (s *RpcServer) Stop(ctx context.Context) error {

    s.stopped.Store(true)

    return nil

}


func (s *RpcServer) Stopped() bool {

    return s.stopped.Load()

}


func NewRpcServer(db *leveldb.Keys, config *RpcServerConfig) (*RpcServer, error) {

    hsmClient, err := hsm.NewHSMClient(context.Background(), config.KeyPath, config.KeyName)

    if err != nil {

       log.Error("new hsm client fail", "err", err)

    }

    return &RpcServer{

       RpcServerConfig: config,

       db:              db,

       HsmClient:       hsmClient,

    }, nil

}


func (s *RpcServer) Start(ctx context.Context) error {

    go func(s *RpcServer) {

       addr := fmt.Sprintf("%s:%d", s.GrpcHostname, s.GrpcPort)

       log.Info("start rpc services", "addr", addr)

       listener, err := net.Listen("tcp", addr)

       if err != nil {

          log.Error("Could not start tcp listener. ")

       }


       opt := grpc.MaxRecvMsgSize(MaxRecvMessageSize)


       gs := grpc.NewServer(

          opt,

          grpc.ChainUnaryInterceptor(

             nil,

          ),

       )

       reflection.Register(gs)


       wallet.RegisterWalletServiceServer(gs, s)


       log.Info("Grpc info", "port", s.GrpcPort, "address", listener.Addr())

       if err := gs.Serve(listener); err != nil {

          log.Error("Could not GRPC services")

       }

    }(s)

    return nil

}


1.1 源码解析


这段代码实现了一个基于 gRPC 的服务,负责启动和管理 WalletService RPC 服务。以下是对代码的详细解析:


常量


const MaxRecvMessageSize = 1024 * 1024 * 30000

定义了gRPC服务的最大消息接收大小(MaxRecvMessageSize)。

值为 30,000 MB,这是一个非常大的值,可能是为了处理极大数据量的场景。

RpcServerConfig 配置结构体


type RpcServerConfig struct {

    GrpcHostname string

    GrpcPort     int

    KeyPath      string

    KeyName      string

    HsmEnable    bool

}


用于配置 RPC 服务。

GrpcHostname: gRPC 服务监听的主机名。

GrpcPort: gRPC 服务监听的端口。

KeyPath 和 KeyName: 配置与 HSM 客户端相关的密钥路径和名称。

HsmEnable: 标志是否启用 HSM(硬件安全模块)。


RpcServer 服务结构体


type RpcServer struct {

    *RpcServerConfig

    db        *leveldb.Keys

    HsmClient *hsm.HsmClient


    wallet.UnimplementedWalletServiceServer

    stopped atomic.Bool

}


RpcServerConfig: 嵌入的配置结构体,存储服务相关的配置信息。

db: 使用 LevelDB 存储密钥信息的数据库实例。

HsmClient: 与 HSM 交互的客户端实例。UnimplementedWalletServiceServer: 自动生成的 gRPC 服务接口,提供未实现的默认方法。

stopped: 原子布尔值,用于标记服务是否已停止。


停止服务方法


func (s *RpcServer) Stop(ctx context.Context) error {

    s.stopped.Store(true)

    return nil

}


func (s *RpcServer) Stopped() bool {

    return s.stopped.Load()

}


Stop 方法:


 将 stopped 设置为 true,表示服务已停止。


Stopped 方法:


 检查 stopped 的当前值,返回服务是否已停止。


NewRpcServer 创建服务实例


func NewRpcServer(db *leveldb.Keys, config *RpcServerConfig) (*RpcServer, error) {

    hsmClient, err := hsm.NewHSMClient(context.Background(), config.KeyPath, config.KeyName)

    if err != nil {

       log.Error("new hsm client fail", "err", err)

    }

    return &RpcServer{

       RpcServerConfig: config,

       db:              db,

       HsmClient:       hsmClient,

    }, nil

}


作用: 创建并初始化一个新的 RpcServer 实例。


关键点: 创建 HSM 客户端 hsm.NewHSMClient。如果创建失败,会记录错误日志,但继续返回一个 RpcServer 实例(可能需要额外处理此错误)。


Start 方法


func (s *RpcServer) Start(ctx context.Context) error {

    go func(s *RpcServer) {

       addr := fmt.Sprintf("%s:%d", s.GrpcHostname, s.GrpcPort)

       log.Info("start rpc services", "addr", addr)

       listener, err := net.Listen("tcp", addr)

       if err != nil {

          log.Error("Could not start tcp listener. ")

       }


       opt := grpc.MaxRecvMsgSize(MaxRecvMessageSize)


       gs := grpc.NewServer(

          opt,

          grpc.ChainUnaryInterceptor(

             nil,

          ),

       )

       reflection.Register(gs)


       wallet.RegisterWalletServiceServer(gs, s)


       log.Info("Grpc info", "port", s.GrpcPort, "address", listener.Addr())

       if err := gs.Serve(listener); err != nil {

          log.Error("Could not GRPC services")

       }

    }(s)

    return nil

}


作用: 启动 gRPC 服务。


详细解析:


监听地址:通过 fmt.Sprintf("%s:%d", s.GrpcHostname, s.GrpcPort) 生成服务监听的地址。 

使用 net.Listen("tcp", addr) 创建 TCP 监听器。

gRPC 服务配置:设置最大接收消息大小 grpc.MaxRecvMsgSize(MaxRecvMessageSize)。

使用 grpc.NewServer 创建 gRPC 服务实例。

服务反射: 调用 reflection.Register(gs) 注册 gRPC 反射服务(通常用于调试)。

服务注册:注册自定义的 WalletService 实现:wallet.RegisterWalletServiceServer(gs, s)。

启动服务:调用 gs.Serve(listener) 启动服务。

日志记录:输出服务启动的日志信息。


3. 接口代码


package rpc


import (

    "context"

    "strconv"


    "github.com/ethereum/go-ethereum/log"

    "github.com/pkg/errors"


    "github.com/dapplink-labs/wallet-sign-go/leveldb"

    "github.com/dapplink-labs/wallet-sign-go/protobuf/wallet"

    "github.com/dapplink-labs/wallet-sign-go/ssm"

)


func (s *RpcServer) GetSupportSignWay(ctx context.Context, in *wallet.SupportSignWayRequest) (*wallet.SupportSignWayResponse, error) {

    if in.Type == "ecdsa" || in.Type == "eddsa" {

       return &wallet.SupportSignWayResponse{

          Code:    strconv.Itoa(1),

          Msg:     "Support this sign way",

          Support: true,

       }, nil

    } else {

       return &wallet.SupportSignWayResponse{

          Code:    strconv.Itoa(0),

          Msg:     "Do not support this sign way",

          Support: false,

       }, nil

    }

}


func (s *RpcServer) ExportPublicKeyList(ctx context.Context, in *wallet.ExportPublicKeyRequest) (*wallet.ExportPublicKeyResponse, error) {

    if in.Number > 10000 {

       return &wallet.ExportPublicKeyResponse{

          Code: strconv.Itoa(1),

          Msg:  "Number must be less than 100000",

       }, nil

    }


    var keyList []leveldb.Key

    var retKeyList []*wallet.PublicKey


    for counter := 0; counter <= int(in.Number); counter++ {

       var priKeyStr, pubKeyStr, decPubkeyStr string

       var err error


       switch in.Type {

       case "ecdsa":

          priKeyStr, pubKeyStr, decPubkeyStr, err = ssm.CreateECDSAKeyPair()

       case "eddsa":

          priKeyStr, pubKeyStr, err = ssm.CreateEdDSAKeyPair()

          decPubkeyStr = pubKeyStr

       default:

          return nil, errors.New("unsupported key type")

       }

       if err != nil {

          log.Error("create key pair fail", "err", err)

          return nil, err

       }


       keyItem := leveldb.Key{

          PrivateKey:     priKeyStr,

          CompressPubkey: pubKeyStr,

       }

       pukItem := &wallet.PublicKey{

          CompressPubkey:   pubKeyStr,

          DecompressPubkey: decPubkeyStr,

       }

       retKeyList = append(retKeyList, pukItem)

       keyList = append(keyList, keyItem)

    }

    isOk := s.db.StoreKeys(keyList)

    if !isOk {

       log.Error("store keys fail", "isOk", isOk)

       return nil, errors.New("store keys fail")

    }

    return &wallet.ExportPublicKeyResponse{

       Code:      strconv.Itoa(1),

       Msg:       "create keys success",

       PublicKey: retKeyList,

    }, nil

}


func (s *RpcServer) SignTxMessage(ctx context.Context, in *wallet.SignTxMessageRequest) (*wallet.SignTxMessageResponse, error) {

    privKey, isOk := s.db.GetPrivKey(in.PublicKey)

    if !isOk {

       return nil, errors.New("get private key by public key fail")

    }


    var signature string

    var err error


    switch in.Type {

    case "ecdsa":

       signature, err = ssm.SignECDSAMessage(privKey, in.MessageHash)

    case "eddsa":

       signature, err = ssm.SignEdDSAMessage(privKey, in.MessageHash)

    default:

       return nil, errors.New("unsupported key type")

    }

    if err != nil {

       return nil, err

    }

    return &wallet.SignTxMessageResponse{

       Code:      strconv.Itoa(1),

       Msg:       "sign tx message success",

       Signature: signature,

    }, nil

}


3.1 源码解析


GetSupportSignWay


func (s *RpcServer) GetSupportSignWay(ctx context.Context, in *wallet.SupportSignWayRequest) (*wallet.SupportSignWayResponse, error) {

    if in.Type == "ecdsa" || in.Type == "eddsa" {

       return &wallet.SupportSignWayResponse{

          Code:    strconv.Itoa(1),

          Msg:     "Support this sign way",

          Support: true,

       }, nil

    } else {

       return &wallet.SupportSignWayResponse{

          Code:    strconv.Itoa(0),

          Msg:     "Do not support this sign way",

          Support: false,

       }, nil

    }

}


功能: 判断是否支持指定的签名方式(ecdsa 或 eddsa)。


逻辑解析:

1) 检查输入的签名类型 in.Type 是否为支持的类型。

2) 如果支持:

   返回响应对象,Support: true,并附带成功信息。

3) 如果不支持:

   返回响应对象,Support: false,并附带错误信息。


ExportPublicKeyList


func (s *RpcServer) ExportPublicKeyList(ctx context.Context, in *wallet.ExportPublicKeyRequest) (*wallet.ExportPublicKeyResponse, error) {

    if in.Number > 10000 {

       return &wallet.ExportPublicKeyResponse{

          Code: strconv.Itoa(1),

          Msg:  "Number must be less than 100000",

       }, nil

    }


    var keyList []leveldb.Key

    var retKeyList []*wallet.PublicKey


    for counter := 0; counter <= int(in.Number); counter++ {

       var priKeyStr, pubKeyStr, decPubkeyStr string

       var err error


       switch in.Type {

       case "ecdsa":

          priKeyStr, pubKeyStr, decPubkeyStr, err = ssm.CreateECDSAKeyPair()

       case "eddsa":

          priKeyStr, pubKeyStr, err = ssm.CreateEdDSAKeyPair()

          decPubkeyStr = pubKeyStr

       default:

          return nil, errors.New("unsupported key type")

       }

       if err != nil {

          log.Error("create key pair fail", "err", err)

          return nil, err

       }


       keyItem := leveldb.Key{

          PrivateKey:     priKeyStr,

          CompressPubkey: pubKeyStr,

       }

       pukItem := &wallet.PublicKey{

          CompressPubkey:   pubKeyStr,

          DecompressPubkey: decPubkeyStr,

       }

       retKeyList = append(retKeyList, pukItem)

       keyList = append(keyList, keyItem)

    }

    isOk := s.db.StoreKeys(keyList)

    if !isOk {

       log.Error("store keys fail", "isOk", isOk)

       return nil, errors.New("store keys fail")

    }

    return &wallet.ExportPublicKeyResponse{

       Code:      strconv.Itoa(1),

       Msg:       "create keys success",

       PublicKey: retKeyList,

    }, nil

}


功能: 根据请求生成密钥对列表,并将结果存储到数据库。

逻辑解析:


1) 检查请求中的 Number 参数。


如果超过 10,000,直接返回错误响应。


2) 循环生成密钥对:


根据 Type 参数调用对应的方法生成密钥对(ecdsa 或 eddsa)。 

将生成的公私钥信息分别存储到 keyList 和 retKeyList。ecdsa: 生成压缩和解压缩公钥。 

eddsa: 仅生成压缩公钥(等于解压缩公钥)。 

如果生成失败,记录日志并返回错误。


3) 调用 StoreKeys 方法将生成的密钥存储到 LevelDB。 


如果存储失败,记录日志并返回错误。


4) 返回成功响应,包含生成的公钥列表。


SignTxMessage


func (s *RpcServer) SignTxMessage(ctx context.Context, in *wallet.SignTxMessageRequest) (*wallet.SignTxMessageResponse, error) {

    privKey, isOk := s.db.GetPrivKey(in.PublicKey)

    if !isOk {

       return nil, errors.New("get private key by public key fail")

    }


    var signature string

    var err error


    switch in.Type {

    case "ecdsa":

       signature, err = ssm.SignECDSAMessage(privKey, in.MessageHash)

    case "eddsa":

       signature, err = ssm.SignEdDSAMessage(privKey, in.MessageHash)

    default:

       return nil, errors.New("unsupported key type")

    }

    if err != nil {

       return nil, err

    }

    return &wallet.SignTxMessageResponse{

       Code:      strconv.Itoa(1),

       Msg:       "sign tx message success",

       Signature: signature,

    }, nil

}


功能: 根据提供的公钥和消息哈希,使用对应的私钥对消息进行签名。


逻辑解析:


1) 从 LevelDB 获取与公钥对应的私钥: 


    如果未找到,返回错误。


2) 根据签名类型 Type 调用对应的签名方法: 


    ecdsa: 使用 ECDSA 方法签名。 

    eddsa: 使用 EdDSA 方法签名。

    如果类型不支持,返回错误。


3) 如果签名失败,返回错误。

4) 返回成功响应,包含生成的签名。


4.LevelDB 代码解析


package leveldb


import (

    "encoding/hex"

    "github.com/ethereum/go-ethereum/log"

    "github.com/syndtr/goleveldb/leveldb"

)


type LevelStore struct {

    *leveldb.DB

}


func NewLevelStore(path string) (*LevelStore, error) {

    handle, err := leveldb.OpenFile(path, nil)

    if err != nil {

       log.Error("open level db file fail", "err", err)

       return nil, err

    }

    return &LevelStore{handle}, nil

}


func (db *LevelStore) Put(key []byte, value []byte) error {

    return db.DB.Put(key, value, nil)

}


func (db *LevelStore) Get(key []byte) ([]byte, error) {

    return db.DB.Get(key, nil)

}


func (db *LevelStore) Delete(key []byte) error {

    return db.DB.Delete(key, nil)

}


func toBytes(dataStr string) []byte {

    dataBytes, _ := hex.DecodeString(dataStr)

    return dataBytes

}


func toString(byteArr []byte) string {

    return hex.EncodeToString(byteArr)

}


这段代码实现了基于 LevelDB 的一个简单键值存储库封装,提供了对数据的基本操作接口(Put、Get 和 Delete)


package leveldb


import "github.com/ethereum/go-ethereum/log"


type Keys struct {

    db *LevelStore

}


func NewKeyStore(path string) (*Keys, error) {

    db, err := NewLevelStore(path)

    if err != nil {

       log.Error("Could not create leveldb database.")

       return nil, err

    }

    return &Keys{

       db: db,

    }, nil

}


func (k *Keys) GetPrivKey(publicKey string) (string, bool) {

    key := []byte(publicKey)

    data, err := k.db.Get(key)

    if err != nil {

       return "0x00", false

    }

    bstr := toString(data)

    return bstr, true

}


func (k *Keys) StoreKeys(keyList []Key) bool {

    for _, item := range keyList {

       key := []byte(item.CompressPubkey)

       value := toBytes(item.PrivateKey)

       err := k.db.Put(key, value)

       if err != nil {

          log.Error("store key value fail", "err", err, "key", key, "value", value)

          return false

       }

    }

    return true

}


这段代码实现了一个密钥存储 (Keys) 模块,基于 LevelDB 提供密钥的存取功能;主要功能是实现 privateKey 的存取。


小结


DappLink的签名机支持两种主要模式:CloudHSM(云硬件安全模块)和TEE(可信执行环境)。这两种模式提供了高安全性的环境用于执行加密操作。签名机目前支持两种常见的数字签名算法:ECDSA(椭圆曲线数字签名算法)和EdDSA(Edwards曲线数字签名算法)。这些功能已经被多家厂商采用,能够提供安全、可靠的数字签名解决方案,广泛应用于加密货币、区块链、金融等领域。

声明:本网站所有相关资料如有侵权请联系站长删除,资料仅供用户学习及研究之用,不构成任何投资建议!