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

SHA256哈希生成Curve25519私钥报错ValueError问题排查

问题:SHA256哈希生成Curve25519私钥时出现长度错误

将秘密口令通过SHA256哈希得到账户私钥,再利用Curve25519算法由私钥生成公钥。但运行代码时出现错误:

ValueError: An X25519 private key is 32 bytes long

已知SHA256返回64位字符串,想请教问题出在哪里,测试代码如下:

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
from hashlib import sha256
from cryptography.hazmat.primitives.kdf.hkdf import HKDF

# 秘密口令
passphrase = "asdasfsdfsjddfueirgnuengigtnsenveigvuneirvneriuvniuvnrsbng"
# SHA256哈希口令
passphrase_sha256 = sha256(passphrase.encode('utf-8')).hexdigest()

# 将哈希传入Curve25519生成密钥
private_key = X25519PrivateKey.from_private_bytes(passphrase_sha256)
peer_public_key = X25519PrivateKey.from_private_bytes(passphrase_sha256).public_key()

问题原因与解决方案

错误根源

  • sha256(...).hexdigest()返回的是64个字符的十六进制字符串,每个ASCII字符占1字节,所以这个字符串实际是64字节长,但Curve25519私钥要求的是32字节的原始二进制数据。
  • 你混淆了“十六进制字符串”和“原始二进制哈希值”:SHA256的哈希结果本质是32字节的二进制数据,hexdigest()只是把它转换成了人类可读的十六进制形式,长度直接翻倍了。

修正后的代码

直接使用SHA256的digest()方法获取原始32字节二进制数据:

from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
from hashlib import sha256

# 秘密口令
passphrase = "asdasfsdfsjddfueirgnuengigtnsenveigvuneirvneriuvniuvnrsbng"
# 获取SHA256原始二进制哈希结果(32字节)
passphrase_hash_bytes = sha256(passphrase.encode('utf-8')).digest()

# 生成Curve25519私钥和公钥
private_key = X25519PrivateKey.from_private_bytes(passphrase_hash_bytes)
peer_public_key = private_key.public_key()

更安全的密钥派生方式

直接用哈希值作为私钥安全性不足,推荐使用HKDF这类标准密钥派生函数,加入盐值和信息字段增强随机性:

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey
from cryptography.hazmat.primitives.kdf.hkdf import HKDF

passphrase = "asdasfsdfsjddfueirgnuengigtnsenveigvuneirvneriuvniuvnrsbng"
# 初始化HKDF,派生32字节的密钥材料
hkdf = HKDF(
    algorithm=hashes.SHA256(),
    length=32,
    salt=None,  # 实际使用时建议添加随机盐值提升安全性
    info=b"curve25519-account-key",  # 自定义信息字段,区分不同用途的密钥
)
derived_key = hkdf.derive(passphrase.encode('utf-8'))

private_key = X25519PrivateKey.from_private_bytes(derived_key)
peer_public_key = private_key.public_key()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:49:51