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

基于NBitcoin的比特币消息签名工具验证失败问题求助

比特币消息签名验证失败问题求助

我需要开发一款比特币系列文本签名工具,选用NBitcoin包实现了签名功能,但生成的签名无法通过标准消息验证工具的校验。

初始实现代码

using System;
using System.Data;
using System.Text;

using NBitcoin;
using NBitcoin.Crypto;
using NBitcoin.DataEncoders;

class Program
{
    static void Main(string[] args)
    {
        var privateKey = new Key();
        var bitcoinPrivateKey = privateKey.GetWif(Network.Main);
        var bitcoinPublicKey = bitcoinPrivateKey.PubKey;
        var address = bitcoinPublicKey.GetAddress(ScriptPubKeyType.Segwit, Network.Main);
        Console.WriteLine(address);

        var message = "test";
        byte[] messageBytes = Encoding.UTF8.GetBytes(message);
        uint256 hash = new uint256(Hashes.SHA256(messageBytes));
        
        var signature = privateKey.Sign(hash);
        var signatureBytes = signature.ToDER();

        string signatureBase64 = Encoders.Base64.EncodeData(signatureBytes);
        Console.WriteLine("Signature: " + signatureBase64);
    }
}

优化后的代码(遵循比特币消息签名标准)

根据提示,我按照比特币消息签名标准调整了代码,但问题依然存在:

static void Main(string[] args)
{
    var privateKey = new Key();
    var bitcoinPrivateKey = privateKey.GetWif(Network.Main);
    var bitcoinPublicKey = bitcoinPrivateKey.PubKey;
    var address = bitcoinPublicKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main);
    Console.WriteLine("Address: " + address);

    var message = "test";

    // Sign the message using the Bitcoin Message Signing standard
    string signatureBase64 = SignBitcoinMessage(privateKey, message);

    Console.WriteLine("Signature: " + signatureBase64);
}

/// <summary>
/// Signs a message using the Bitcoin Message Signing standard.
/// This method prepares the message with the appropriate prefix and length encoding, 
/// hashes it twice with SHA-256, and then signs it using the provided private key.
/// The resulting signature is returned in Base64 format.
/// </summary>
/// <param name="privateKey">The private key to sign the message with.</param>
/// <param name="message">The message to be signed.</param>
/// <returns>A Base64 encoded signature of the message.</returns>
static string SignBitcoinMessage(Key privateKey, string message)
{
    byte[] messageBytes = Encoding.UTF8.GetBytes(message);

    // Structure for the message in Bitcoin Signed Message format
    byte[] prefixBytes = Encoding.UTF8.GetBytes("Bitcoin Signed Message:\n");
    byte[] lengthBytes = new VarInt((ulong)messageBytes.Length).ToBytes();

    byte[] fullMessage = new byte[prefixBytes.Length + lengthBytes.Length + messageBytes.Length];
    Buffer.BlockCopy(prefixBytes, 0, fullMessage, 0, prefixBytes.Length);
    Buffer.BlockCopy(lengthBytes, 0, fullMessage, prefixBytes.Length, lengthBytes.Length);
    Buffer.BlockCopy(messageBytes, 0, fullMessage, prefixBytes.Length + lengthBytes.Length, messageBytes.Length);

    // Double SHA-256 hashing
    uint256 hash = new uint256(Hashes.SHA256(Hashes.SHA256(fullMessage)));

    ECDSASignature signature = privateKey.Sign(hash);

    // Serialize and format the signature
    var sigBytes = signature.ToCompact();
    byte[] fullSignature = new byte[sigBytes.Length + 1];
    fullSignature[0] = (byte)(27 + 4 + (privateKey.PubKey.IsCompressed ? 4 : 0)); // Include key flag
    Buffer.BlockCopy(sigBytes, 0, fullSignature, 1, sigBytes.Length);

    return Encoders.Base64.EncodeData(fullSignature);
}

求助需求

调整代码后签名仍无法通过验证,求分析失败原因并给出解决方法。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 00:43:15