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
相关产品推荐
相关产品推荐

