You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用HEX格式私钥生成secp256k1签名 解决Hive网络PostingKey签名问题

Hive 网络PostingKey签名问题解决方案

1 原BouncyCastle代码错误修复

原代码的核心错误点:

  • signer.Init第一个参数传反,签名操作需要传true,false是验签用途
  • 未指定Hive使用的secp256k1曲线参数,直接初始化空ECDomainParameters必然失败
  • BigInteger构造未处理字节序,C#默认的BigInteger为小端序,私钥字节为大端序,需要补充参数修正
    修复后的BouncyCastle代码示例:
using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.Math;
using System.Text;

public static class Signer
{
    // 预加载secp256k1曲线参数
    private static readonly ECDomainParameters Secp256k1Params;
    static Signer()
    {
        var secp256k1 = SecNamedCurves.GetByName("secp256k1");
        Secp256k1Params = new ECDomainParameters(secp256k1.Curve, secp256k1.G, secp256k1.N, secp256k1.H);
    }

    public static byte[] Sign(string message, byte[] privateKey)
    {
        var signer = new ECDsaSigner(new HMacDsaKCalculator(new Org.BouncyCastle.Crypto.Digests.Sha256Digest()));
        // 修正BigInteger字节序问题,1代表大端无符号字节
        var bigIntPrivateKey = new BigInteger(1, privateKey);
        var parameters = new ECPrivateKeyParameters(bigIntPrivateKey, Secp256k1Params);
        // 签名操作第一个参数必须传true
        signer.Init(true, parameters);

        var messageBytes = Encoding.UTF8.GetBytes(message);
        // ECDSA要求对消息哈希后再签名,不能直接传原消息字节
        var messageHash = System.Security.Cryptography.SHA256.HashData(messageBytes);
        var signature = signer.GenerateSignature(messageHash);

        // 后续按Hive要求拼接恢复码、r、s、校验位即可
        return signature;
    }
}

2 Cryptography.ECDSA库问题修复

2.1 相同入参签名不一致属于正常现象

ECDSA签名默认使用随机k值生成签名,只要r、s符合规范,每次生成的签名不同完全不影响验签结果,eosjs_ecc的签名逻辑也有相同特性。

2.2 验签不通过的核心问题

当前代码大概率是没有先对原消息做SHA256哈希就直接传入签名方法,Hive网络的签名逻辑要求先对原始消息做SHA256运算,再对哈希结果签名,而非直接对原消息签名。
修复后的代码示例:

using Cryptography.ECDSA;
using System.Security.Cryptography;
using System.Text;

public static string SignHiveMessage(string message, byte[] privateKey)
{
    // 第一步:对原消息做SHA256哈希
    var messageHash = SHA256.HashData(Encoding.UTF8.GetBytes(message));
    // 传入哈希值而非原消息做签名
    var buffer = Secp256K1Manager.SignCompressedCompact(messageHash, privateKey);
    var checksum = Ripemd160Manager.GetHash(buffer);
    var signatureArray = buffer.Concat(checksum.Take(4)).ToArray();
    var result = Base58.Encode(signatureArray);
    return $"SIG_K1_{result}";
}

2.3 私钥解码注意事项

你提供的示例私钥为WIF格式,解码成32字节私钥时需要注意:

  • 先对完整WIF字符串做Base58解码
  • 去掉首位的版本字节(0x80)和末尾4位校验字节,中间32字节才是真实私钥
  • 解码完成后需要校验校验位,避免私钥解析错误

内容的提问来源于stack exchange,提问作者Assassin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 09:27:04