使用比特币私钥签署消息

问题描述 投票:0回答:1

我需要创建一个比特币家族文本签名工具。

研究这个问题后,我找到了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);
    }
}

但由于某种原因,生成的签名对于 https://www.verifybitcoinmessage.com/

无效

**更新了

根据chatgpt,我需要使用

Bitcoin Message Signing
标准签署消息

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);
}

但这也没有帮助

c# bitcoin nbitcoin
1个回答
1
投票

我使用了错误的软件包。 正确的包是NBitcoin-std2

using NBitcoin;

Key Key = new Key(); //Create private key
//We can take private key
var privateKey = Key.GetBitcoinSecret(Network.Main);

//Get the public key, and derive the address on the Main network
BitcoinAddress address = privateKey.PubKey.GetAddress(ScriptPubKeyType.Segwit, Network.Main);
Console.WriteLine("Address:" + address + "\n");

//For the sign to data , create secret object.
BitcoinSecret secret = new BitcoinSecret(Key, Network.Main);

string message = $"test";
Console.WriteLine("Message:" + message + "\n");
//sign message with private key.
string signature = secret.PrivateKey.SignMessage(message);
Console.WriteLine("Signature:" + signature + "\n");
© www.soinside.com 2019 - 2024. All rights reserved.