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
核心修改点
- 私钥初始化:用
OpenSSL::PKey::EC.new()创建空对象,先设置曲线组group再赋值private_key,此时对象处于可变状态,可正常设置密钥参数。 - 公钥初始化:单独创建公钥对象,避免复用签名用的私钥对象,规避不可变特性限制。
- 独立密钥实例:签名和验证使用不同的密钥对象,符合OpenSSL 3.0的不可变设计原则。
内容的提问来源于stack exchange,提问作者Yk Poh
相关产品推荐
相关产品推荐

