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

Ruby加解密练习(ARGV)求助:encode正常但decode失败

Troubleshooting Your Ruby Encrypt-Decrypt Program's Decode Issue

Hey there! Let's break down why your decode function is throwing that "key too large" error, especially since your encode works perfectly. Based on what you described, this is almost always a mix-up between keys and ciphertext, or a mismatch between your encryption algorithm's requirements and how you're handling input.

Common Causes & Fixes

1. You're Using Encoded Ciphertext as a Key (Big Mistake!)

Symmetric encryption (which I assume you're using with OpenSSL) requires the same secret key for both encrypting and decrypting. The output from your encode function is the ciphertext (encrypted data), not a key. If you're passing that ciphertext into your decode function as the "key", it's way longer than valid key lengths for algorithms like AES—hence the "key too large" error.

Fix:

  • Your program should accept a separate, fixed key via ARGV for both modes. For example:
    • Encode: ruby your_script.rb encode your_secret_key "plaintext here"
    • Decode: ruby your_script.rb decode your_secret_key "ciphertext_from_encode"

2. Key Length Doesn't Match Your Encryption Algorithm

OpenSSL's cipher algorithms have strict key length requirements:

  • AES-128: 16 bytes (128 bits)
  • AES-192: 24 bytes (192 bits)
  • AES-256: 32 bytes (256 bits)

If you initialized your cipher with, say, AES-256-CBC but passed a key longer than 32 bytes (or shorter!), you'll get errors. Accidentally passing ciphertext (which is way longer than 32 bytes) as the key triggers exactly this issue.

Fix:

  • Add a check to validate key length before encryption/decryption:
    # Example for AES-256
    if key.bytesize != 32
      puts "Error: AES-256 requires a 32-byte key (yours is #{key.bytesize} bytes)"
      exit 1
    end
    

3. You're Forgetting to Decode Base64 Input

If your encode function outputs Base64-encoded text (common to make ciphertext printable), you need to decode it back to binary before passing it to the decrypt function. Skipping this step and passing the Base64 string directly (as a key or ciphertext) inflates the byte length, causing key errors.

Fix:

  • When handling decode input, use Base64.decode64() to convert the printable string back to binary:
    decoded_ciphertext = Base64.decode64(ARGV[2]) # Assuming ciphertext is the 3rd ARGV param
    

4. ARGV Parameter Order is Mixed Up

Double-check how you're parsing ARGV. If your code expects the key as the second argument but you're passing ciphertext there instead, that's a quick way to trigger the "key too large" error.

Fix:

  • Add a usage message to clarify parameter order:
    if ARGV.size < 3
      puts "Usage: ruby #{$0} [encode/decode] <secret_key> <content>"
      exit 1
    end
    mode = ARGV[0]
    key = ARGV[1]
    content = ARGV[2]
    

Example Working Snippet

Here's a trimmed-down, correct version of what your code should look like (using AES-256-CBC, a standard choice):

#!/usr/bin/ruby
require "openssl"
require "base64"

def encode(key, plaintext)
  cipher = OpenSSL::Cipher.new('AES-256-CBC')
  cipher.encrypt
  cipher.key = key
  iv = cipher.random_iv # IV is required for decryption—don't lose it!
  encrypted = cipher.update(plaintext) + cipher.final
  Base64.strict_encode64(iv + encrypted) # Bundle IV and ciphertext together
end

def decode(key, encrypted_str)
  decoded = Base64.strict_decode64(encrypted_str)
  cipher = OpenSSL::Cipher.new('AES-256-CBC')
  cipher.decrypt
  iv = decoded[0...16] # Extract IV (first 16 bytes for AES block size)
  cipher.iv = iv
  cipher.key = key
  cipher.update(decoded[16..-1]) + cipher.final # Decrypt the actual ciphertext
end

# Handle input validation and parsing
if ARGV.size < 3
  puts "Usage: ruby #{$0} [encode/decode] <32_byte_key> <content>"
  exit 1
end

mode, key, content = ARGV

# Validate key length for AES-256
if key.bytesize != 32
  puts "Error: AES-256 requires a 32-byte key (yours is #{key.bytesize} bytes)"
  exit 1
end

begin
  if mode == "encode"
    puts encode(key, content)
  elsif mode == "decode"
    puts decode(key, content)
  else
    puts "Invalid mode: use 'encode' or 'decode'"
  end
rescue => e
  puts "Error: #{e.message}"
end

Quick Test Steps

  1. Generate a valid 32-byte key (e.g., openssl rand 32 for raw binary, or openssl rand -base64 24 to get a Base64-encoded 32-byte key).
  2. Encode a test string: ruby your_script.rb encode "your_32_byte_key" "hello world"
  3. Copy the output ciphertext, then decode it: ruby your_script.rb decode "your_32_byte_key" "copied_ciphertext"

This should run without the "key too large" error.

内容的提问来源于stack exchange,提问作者Ofir Sasson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:41:47