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

OpenSSL 3.0下pkeys不可变,如何用已有密钥加密消息?

问题:OpenSSL 3.0下使用已有EC密钥进行签名与验证时触发不可变错误

问题背景

在OpenSSL 3.0环境中,尝试通过修改OpenSSL::PKey::EC对象的private_key/public_key属性复用已有密钥进行消息签名和验证时,触发pkeys are immutable on OpenSSL 3.0的OpenSSL::PKey::PKeyError错误,错误发生在Fastfile第821行。

环境信息

  • ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [arm64-darwin21]
  • openssl (3.1.0, default: 2.2.0)
  • fastlane | 2.212.2 | ✅ Up-To-Date

原错误代码

def get_force_update_message
    message = "message"
    private_key = "sample_private_key"
    public_key = "sample_public_key"

    # encrypt
    group = OpenSSL::PKey::EC::Group.new('secp256k1')
    key = OpenSSL::PKey::EC.new(group)
    key.private_key = OpenSSL::BN.new(private_key, 16)

    signature = key.dsa_sign_asn1(message)
    signature_base64 = Base64.encode64(signature).gsub("\n", "")

    # verify
    public_key_bn = OpenSSL::BN.new(public_key, 16)
    key.public_key = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
    key.dsa_verify_asn1(message, signature)

    return "#{message}&#{signature_base64}"
end

错误详情

[17:13:51]: Error in your Fastfile at line 821
[17:13:51]:     819:        group = OpenSSL::PKey::EC::Group.new('secp256k1')
[17:13:51]:     820:        key = OpenSSL::PKey::EC.new(group)
[17:13:51]:  => 821:        key.private_key = OpenSSL::BN.new(private_key, 16)
[17:13:51]:     822:    
[17:13:51]:     823:        signature = key.dsa_sign_asn1(message)
[17:13:51]: pkeys are immutable on OpenSSL 3.0

+------+----------------------+-------------+
|             fastlane summary              |
+------+----------------------+-------------+
| Step | Action               | Time (in s) |
+------+----------------------+-------------+
| 1    | default_platform     | 0           |
| 2    | xcodes               | 0           |
| 3    | ensure_env_vars      | 0           |
| 4    | set_info_plist_value | 0           |
| 5    | ensure_env_vars      | 0           |
+------+----------------------+-------------+

[17:13:51]: fastlane finished with errors

Looking for related GitHub issues on fastlane/fastlane...

Found no similar issues. To create a new issue, please visit:
https://github.com/fastlane/fastlane/issues/new
Run `fastlane env` to append the fastlane environment to your issue
Fastfile:821:in `private_key=': \e[31m[!] pkeys are immutable on OpenSSL 3.0\e[0m (OpenSSL::PKey::PKeyError)
    from Fastfile:821:in `get_force_update_message'
    from Fastfile:252:in `block (2 levels) in parsing_binding'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane.rb:33:in `call'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:49:in `block in execute'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `chdir'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/runner.rb:45:in `execute'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/lane_manager.rb:47:in `cruise_lane'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/command_line_handler.rb:36:in `handle'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:110:in `block (2 levels) in run'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:124:in `run!'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:354:in `run'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/commands_generator.rb:43:in `start'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/fastlane/lib/fastlane/cli_tools_distributor.rb:123:in `take_off'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/gems/fastlane-2.212.2/bin/fastlane:23:in `<top (required)>'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `load'
    from /opt/homebrew/Cellar/fastlane/2.212.2/libexec/bin/fastlane:25:in `<main>'

解决方案

OpenSSL 3.0中,OpenSSL::PKey::EC.new(group)创建的密钥对象默认不可变,无法修改其密钥属性。需调整初始化方式,从已有密钥参数创建可变状态的密钥对象,且签名、验证使用独立实例。

修改后的完整代码

def get_force_update_message
    message = "message"
    private_key = "sample_private_key"
    public_key = "sample_public_key"

    # 初始化椭圆曲线组
    group = OpenSSL::PKey::EC::Group.new('secp256k1')

    # 签名流程:创建私钥对象并签名
    private_key_obj = OpenSSL::PKey::EC.new
    private_key_obj.group = group
    private_key_obj.private_key = OpenSSL::BN.new(private_key, 16)
    # 自动计算公钥(无需公钥可省略此步骤)
    private_key_obj.public_key = private_key_obj.private_key.public_key(group)

    signature = private_key_obj.dsa_sign_asn1(message)
    signature_base64 = Base64.encode64(signature).gsub("\n", "")

    # 验证流程:创建公钥对象并验证签名
    public_key_bn = OpenSSL::BN.new(public_key, 16)
    public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
    public_key_obj = OpenSSL::PKey::EC.new(group)
    public_key_obj.public_key = public_key_point

    # 执行验证,返回布尔值表示验证结果
    verification_success = public_key_obj.dsa_verify_asn1(message, signature)

    return "#{message}&#{signature_base64}"
end

核心修改点

  1. 私钥初始化:用OpenSSL::PKey::EC.new()创建空对象,先设置曲线组group再赋值private_key,此时对象处于可变状态,可正常设置密钥参数。
  2. 公钥初始化:单独创建公钥对象,避免复用签名用的私钥对象,规避不可变特性限制。
  3. 独立密钥实例:签名和验证使用不同的密钥对象,符合OpenSSL 3.0的不可变设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 04:54:54