Erlang使用crypto:sign签名时无法获取ECDSA私钥的解决求助
问题:使用prime256v1曲线生成的ECDH密钥无法用于ECDSA签名
我尝试实现使用prime256v1曲线的ECDH签名的VAPID Claim,测试代码如下:
test() -> Msg = <<"test">>, {PubKey, PrivKey} = crypto:generate_key(ecdh, prime256v1), ?LOG(notice,"PubKey:~p~n",[PubKey]), ?LOG(notice," PrivKey:~p~n",[PrivKey]), Signature = crypto:sign(ecdsa,sha256,Msg,PrivKey), ?LOG(notice,"~p~n",[Signature]).
运行代码时出现如下错误:
** exception error: {badarg,{"pkey.c",363},"Couldn't get ECDSA private key"} in function crypto:sign/5 (crypto.erl, line 1455) *** argument 4: Couldn't get ECDSA private key *** (Found in the internal file pkey.c at line 363)
解决思路
- 密钥类型不匹配:
crypto:generate_key(ecdh, prime256v1)生成的是ECDH密钥交换专用的密钥对,其格式与ECDSA签名所需的密钥不兼容。ECDH和ECDSA虽然同属椭圆曲线算法,但密钥的内部表示和用途不同。 - 替换密钥生成函数:改用
crypto:generate_key(ecdsa, prime256v1)生成ECDSA专用密钥对,修改后的代码如下:test() -> Msg = <<"test">>, {PubKey, PrivKey} = crypto:generate_key(ecdsa, prime256v1), ?LOG(notice,"PubKey:~p~n",[PubKey]), ?LOG(notice," PrivKey:~p~n",[PrivKey]), Signature = crypto:sign(ecdsa, sha256, Msg, PrivKey), ?LOG(notice,"~p~n",[Signature]). - 匹配VAPID规范要求:VAPID明确要求使用基于P-256(prime256v1)曲线的ECDSA密钥对来签名JWT Claim,因此必须使用ECDSA类型的密钥生成方式。
- 检查Erlang版本:旧版OTP的crypto模块对EC密钥的处理可能存在兼容性问题,建议使用OTP 21及以上版本,确保ECDSA与prime256v1的交互正常。
内容的提问来源于stack exchange,提问作者Anton Prokofiev
相关产品推荐
相关产品推荐

