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

Ruby中出现bad decrypt错误,Rails扩展String类解密失败求助

Fixing the "bad decrypt" Error in Your Rails String Encryption Extension

Let's break down why your code is throwing that "bad decrypt" error and fix it step by step.

What's Wrong With the Original Code?

You've got three critical issues here:

  1. You're ignoring the passed key
    In both encrypt and decrypt, you overwrite the input key with cipher.random_key. That means you're encrypting with a random key, then trying to decrypt with a completely different random key—of course it fails!
  2. No handling for Initialization Vector (IV)
    DES-EDE3-CBC is a block cipher mode that requires an IV. OpenSSL generates a random IV automatically, but you never save or reuse it for decryption. Mismatched IVs will cause decryption to fail.
  3. Redundant byte manipulation
    The line [self].pack("H*").unpack("C*").pack("c*") is unnecessary and can introduce encoding issues. [self].pack("H*") already converts hex to binary correctly.

Fixed Code Implementation

Here's the corrected version with explanations:

require 'openssl'
require 'digest'

class String
  def encrypt(key)
    cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
    
    # Process the input key to ensure it's the required 24 bytes for DES-EDE3
    processed_key = Digest::SHA256.hexdigest(key)[0, 24]
    cipher.key = processed_key
    
    # Generate and save a random IV (required for CBC mode)
    iv = cipher.random_iv
    encrypted_data = cipher.update(self) + cipher.final
    
    # Return IV + encrypted data (both as hex, separated by a colon)
    "#{iv.unpack('H*')[0].upcase}:#{encrypted_data.unpack('H*')[0].upcase}"
  end

  def decrypt(key)
    # Split the stored IV and encrypted data
    iv_hex, encrypted_hex = split(':', 2)
    return nil unless iv_hex && encrypted_hex

    cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
    
    # Use the same processed key as encryption
    processed_key = Digest::SHA256.hexdigest(key)[0, 24]
    cipher.key = processed_key
    
    # Reuse the exact IV from encryption
    cipher.iv = [iv_hex].pack('H*')
    
    # Convert hex back to binary and decrypt
    encrypted_data = [encrypted_hex].pack('H*')
    cipher.update(encrypted_data) + cipher.final
  rescue OpenSSL::Cipher::CipherError
    # Handle decryption failures gracefully
    nil
  end
end

Key Improvements Explained

  • Preserve the input key: We now use the passed key (processed to meet DES-EDE3's 24-byte requirement) instead of generating random keys for every operation.
  • IV management: We generate a random IV during encryption, include it in the output, and reuse it for decryption—this is mandatory for CBC mode.
  • Simplified byte conversion: Removed redundant unpack/pack steps that could break data integrity.
  • Error handling: Added a rescue block to catch cipher errors and return nil instead of crashing.

Usage Example

# Test the implementation
secret_key = "my_secure_master_key_123"
original_text = "This is a secret message!"

encrypted = original_text.encrypt(secret_key)
decrypted = encrypted.decrypt(secret_key)

puts "Original: #{original_text}"
puts "Encrypted: #{encrypted}"
puts "Decrypted: #{decrypted}" # Should match the original text

内容的提问来源于stack exchange,提问作者The Whiz of Oz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:07:27