{"record":{"id":"f0bd7b6d36612826","repo":"ruby/ruby","slug":"incorrect-signing-key-for-signing","errorCode":null,"errorMessage":"incorrect signing key for signing","messagePattern":"incorrect signing key for signing","errorType":"exception","errorClass":"Gem::Security::Exception","httpStatus":null,"severity":"error","filePath":"lib/rubygems/security.rb","lineNumber":568,"sourceCode":"    end\n\n    extensions = extensions.merge \"subjectAltName\" => alt_name.value if\n      alt_name\n\n    issuer_alt_name = signing_cert.extensions.find do |extension|\n      extension.oid == \"subjectAltName\"\n    end\n\n    extensions = extensions.merge \"issuerAltName\" => issuer_alt_name.value if\n      issuer_alt_name\n\n    signed = create_cert signee_subject, signee_key, age, extensions, serial\n    signed.issuer = signing_cert.subject\n\n    begin\n      signed.sign signing_key, Gem::Security::DIGEST_NAME\n    rescue OpenSSL::PKey::PKeyError, ArgumentError\n      raise Gem::Security::Exception,\n        \"incorrect signing key for signing\"\n    end\n  end\n\n  ##\n  # Returns a Gem::Security::TrustDir which wraps the directory where trusted\n  # certificates live.\n\n  def self.trust_dir\n    return @trust_dir if @trust_dir\n\n    dir = File.join Gem.user_home, \".gem\", \"trust\"\n\n    @trust_dir ||= Gem::Security::TrustDir.new dir\n  end\n\n  ##\n  # Enumerates the trusted certificates via Gem::Security::TrustDir.","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/ruby/ruby/blob/0e5b888e1c355f3f728f2659f085820937dada48/lib/rubygems/security.rb#L550-L586","documentation":"Inside certificate creation (Gem::Security create_cert path used by gem cert --sign), RubyGems executes signed.sign(signing_key, Gem::Security::DIGEST_NAME) with the fixed SHA-256 digest and rescues OpenSSL::PKey::PKeyError/ArgumentError into this error. It fires when the key cannot sign with SHA-256: a key that does not match the signing certificate, or a key type incompatible with the digest (DSA keys cannot sign SHA-256).","triggerScenarios":"gem cert --sign cert.pem -K key.pem where the key is the wrong pair or a DSA key while DIGEST_NAME is SHA256; programmatic create_cert calls with mismatched signing_key/signing_cert; passing an encrypted key that failed to decrypt into a usable object.","commonSituations":"Signing child certificates with a CA key of the wrong type; mixed RSA/DSA assets from legacy setups; scripts that load the public key instead of the private key.","solutions":["Pass the exact private key that pairs with the signing certificate (-K / signing_key); verify with cert.check_private_key(key)","Use an RSA or EC key pair — DSA keys cannot be combined with the SHA-256 digest this code path fixes","Sanity-check the key loads as a private key: OpenSSL::PKey.read(File.read(key_path)) before signing"],"exampleFix":"# before\n$ gem cert --sign child.pem -K dsa_ca_key.pem\n#=> incorrect signing key for signing\n\n# after: sign with the RSA private key matching the CA cert\n$ gem cert --sign child.pem -K rsa_ca_key.pem","handlingStrategy":"validation","validationCode":"cert = OpenSSL::X509::Certificate.new(File.read(signing_cert_path))\nkey  = OpenSSL::PKey.read(File.read(key_path))\nraise \"key does not match signing cert\" unless cert.check_private_key(key)\nraise \"DSA key cannot sign with SHA-256\" if key.is_a?(OpenSSL::PKey::DSA)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass the private key that pairs with the signing certificate; verify with check_private_key before gem cert --sign","Standardize on RSA or EC key pairs for signing — DSA is incompatible with the SHA-256 digest this path uses","Load keys via OpenSSL::PKey.read and confirm you got a private key, not the public half"],"tags":["rubygems","gem-signing","certificates","keys","openssl","digest"],"backgroundTag":"private-key-certificate-mismatch","analyzedSha":"0e5b888e1c355f3f728f2659f085820937dada48","analyzedAt":"2026-08-21T14:25:43.473Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}