BSV消息加密解密Skill wallet-encrypt-decrypt

这个技能用于在BSV区块链环境中,使用@bsv/sdk库进行消息的加密和解密。它支持ECDH密钥协商和AES-256-GCM加密算法,适用于安全通信、数据传输等场景。关键词:BSV, 加密, 解密, ECDH, AES-256-GCM, @bsv/sdk, 区块链安全。

加密算法 0 次安装 0 次浏览 更新于 3/15/2026

name: wallet-encrypt-decrypt description: 当用户请求"使用BSV密钥加密消息"、“使用私钥解密”、“ECDH加密”、“AES-256-GCM BSV”、“EncryptedMessage”、“BRC-2加密”,或需要使用BSV密钥和@bsv/sdk加密/解密数据时,应使用此技能。

BSV 消息加密

使用 @bsv/sdk 在各方之间加密和解密消息。

推荐:使用 @bsv/sdk 中的 EncryptedMessage

@bsv/sdk 提供 EncryptedMessage 用于安全消息加密。这是首选方法 - 避免自定义加密实现。

import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'

const sender = PrivateKey.fromRandom()
const recipient = PrivateKey.fromRandom()

// 加密:发送方使用其私钥 + 接收方的公钥
const message = Utils.toArray('Secret message', 'utf8')
const encrypted = EncryptedMessage.encrypt(message, sender, recipient.toPublicKey())

// 解密:接收方使用其私钥
const decrypted = EncryptedMessage.decrypt(encrypted, recipient)
const plaintext = Utils.toUTF8(decrypted)

两种加密模式

模式 1:静态-静态 ECDH(双方都有密钥)

当双方都有已建立的密钥对时使用(例如,BAP身份、paymail地址)。

import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'

// Alice 和 Bob 都有持久密钥
const alice = PrivateKey.fromWif('L1...')
const bob = PrivateKey.fromWif('K1...')

// Alice 加密给 Bob
const ciphertext = EncryptedMessage.encrypt(
  Utils.toArray('Hello Bob', 'utf8'),
  alice,
  bob.toPublicKey()
)

// Bob 解密来自 Alice 的消息
const plaintext = EncryptedMessage.decrypt(ciphertext, bob)

使用场景:

  • 点对点加密消息传递
  • 加密备份到自己的密钥
  • 已知身份之间的通信

模式 2:ECIES 风格(临时发送方密钥)

当发送方没有持久身份时使用(例如,浏览器到服务器)。

import { PrivateKey, EncryptedMessage, Utils } from '@bsv/sdk'

// 服务器有持久密钥,客户端生成临时密钥
const serverKey = PrivateKey.fromWif('L1...')
const ephemeralClient = PrivateKey.fromRandom()

// 客户端加密(临时 → 服务器)
const encrypted = EncryptedMessage.encrypt(
  Utils.toArray('sensitive data', 'utf8'),
  ephemeralClient,
  serverKey.toPublicKey()
)

// 包含临时公钥以便服务器解密
const payload = {
  ephemeralPub: ephemeralClient.toPublicKey().toString(),
  ciphertext: Utils.toHex(encrypted)
}

// 服务器使用临时公钥解密
const clientPub = PublicKey.fromString(payload.ephemeralPub)
// 注意:EncryptedMessage.decrypt 需要密文中嵌入的发送方信息

使用场景:

  • 浏览器到服务器加密
  • 单向安全通道
  • 前向保密(每条消息使用新密钥)

ECDH 密钥协商工作原理

双方推导出相同的共享密钥:

Alice: alicePrivKey × bobPubKey = sharedPoint
Bob:   bobPrivKey × alicePubKey = sharedPoint

共享点然后用于推导 AES-256-GCM 加密的对称密钥。

API 参考

EncryptedMessage.encrypt()

static encrypt(
  message: number[],      // 明文作为字节数组
  sender: PrivateKey,     // 发送方的私钥
  recipient: PublicKey    // 接收方的公钥
): number[]               // 加密的字节

EncryptedMessage.decrypt()

static decrypt(
  ciphertext: number[],   // 来自 encrypt() 的加密字节
  recipient: PrivateKey   // 接收方的私钥
): number[]               // 解密的明文字节

实用函数

// 字符串转字节
Utils.toArray('hello', 'utf8')  // number[]

// 字节转字符串
Utils.toUTF8([104, 101, 108, 108, 111])  // 'hello'

// 字节转十六进制
Utils.toHex([1, 2, 3])  // '010203'

// 十六进制转字节
Utils.toArray('010203', 'hex')  // [1, 2, 3]

安全特性

  • 认证加密:AES-256-GCM 提供机密性和完整性
  • 密钥协商:ECDH 确保只有目标接收方可以解密
  • 无密钥传输:私钥从不离开其所有者

常见错误

不要自定义加密实现

错误:手动实现 ECDH + AES

// 不要这样做 - 使用 EncryptedMessage 代替
const sharedSecret = myPrivKey.deriveSharedSecret(theirPubKey)
const aesKey = sha256(sharedSecret)
// ... 手动 AES 加密

正确:使用 SDK 的内置类

const encrypted = EncryptedMessage.encrypt(message, sender, recipient)

不要混淆加密与认证

  • 加密(此技能):隐藏消息内容
  • 认证bitcoin-auth):证明发送方身份

对于认证 + 加密的通信,同时使用:

// 加密载荷
const encrypted = EncryptedMessage.encrypt(payload, sender, recipient)

// 签署请求(证明发送方身份)
const authToken = getAuthToken({ privateKeyWif, requestPath, body })