如何在 Ruby 中使用('DES/CBC/PKCS5Padding'模式)实现 DES 加密?

Posted

技术标签:

【中文标题】如何在 Ruby 中使用(\'DES/CBC/PKCS5Padding\'模式)实现 DES 加密?【英文标题】:How to implement DES encrypting with ('DES/CBC/PKCS5Padding' mode) in Ruby?如何在 Ruby 中使用('DES/CBC/PKCS5Padding'模式)实现 DES 加密? 【发布时间】:2014-11-20 07:50:06 【问题描述】:

我从第三部分公司收到了一些 DES 加密的东西。我无法用红宝石解密它。但它适用于我的java代码。


这里是java代码:

public class Main 

public static void main(String[] args) 
    try 
        System.out.println(encrypt("12345678", "abc", "12345678"));
        //System.out.println(encrypt("12345678", "ABC", "12345678"));


        System.out.println(decrypt("12345678", "9YR6ZPdZufM=", "12345678"));
        //System.out.println(decrypt("12345678", "6rtTnrF34mPkJ5SO3RiaaQ==", "12345678"));

     catch (Exception e) 
        e.printStackTrace();
    


public static String encrypt(String key, String str, String ivString) throws Exception 
    DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    Key secretKey = keyFactory.generateSecret(desKeySpec);

    IvParameterSpec iv = new IvParameterSpec(ivString.getBytes());
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
    byte[] bytes = cipher.doFinal(str.getBytes());
    dumpHex(bytes);

    return Base64.encode(bytes);


public static void dumpHex(byte[] bytes) 
    for (byte b : bytes) 
        System.out.println(String.format("%02x",b&0xff));
    
    System.out.println(bytesToHex(bytes));


final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) 
    char[] hexChars = new char[bytes.length * 2];
    for ( int j = 0; j < bytes.length; j++ ) 
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    
    return new String(hexChars);


public static String decrypt(String key, String str, String ivString) throws Exception 
    byte[] data = Base64.decode(str);
    dumpHex(data);
    DESKeySpec dks = new DESKeySpec(key.getBytes());
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    Key secretKey = keyFactory.generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    IvParameterSpec iv = new IvParameterSpec(ivString.getBytes());
    cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
    byte[] decryptedBytes = cipher.doFinal(data);
    return new String(decryptedBytes, "gb2312");

我在 ruby​​ 中找不到相同的 DES 模式('DES/CBC/PKCS5Padding')。当我尝试加密相同的字符串时,我得到了不同的结果。


这是我的 ruby​​ 源代码:

class Des
  require 'openssl'
  require 'base64'
  ALG = 'DES-EDE3-CBC'
  KEY = "12345678"
  DES_KEY = "12345678"

  def encode(str)
    des = OpenSSL::Cipher::Cipher.new(ALG)
    des.pkcs5_keyivgen(KEY, DES_KEY)
    des.encrypt
    cipher = des.update(str) + des.final
    pp cipher.length
    pp cipher.unpack('H*')[0]
    return Base64.encode64(cipher)
  end

  def decode(str)
    str = Base64.decode64(str)
    pp str.unpack('H*')[0]
    des = OpenSSL::Cipher::Cipher.new(ALG)
    des.pkcs5_keyivgen(KEY, DES_KEY)
    des.decrypt
    des.update(str) + des.final
  end

  def KEY()
    pp KEY.length
    KEY
  end

  def DES_KEY()
    pp DES_KEY.length
    DES_KEY
  end
end

我用java加密'abc',得到“9YR6ZPdZufM=”。但是在 ruby​​ 版本中得到“5SHCjTOrygg=”。这让我很困惑。

【问题讨论】:

PKCS#5 是基于密码的加密。您需要直接在 Ruby 中访问密钥字节,或者 - 如果您使用密码 - 您需要在 Java 中使用 PBE。 【参考方案1】:

我在 ruby​​ 代码中更改了一些配置,它可以工作。但我不知道为什么......

def DES
    ALG = 'DES-EDE-CBC'
    KEY = "1234567812345678"
    DES_KEY = "12345678"

【讨论】:

以上是关于如何在 Ruby 中使用('DES/CBC/PKCS5Padding'模式)实现 DES 加密?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 代码中使用 ruby​​-linter?

Ruby:如何在Ruby块中使用Merge方法

如何在 Sass 中使用 Ruby/Rails 变量?

如何在 ruby​​ 中使用来自 yaml 的登录凭据

如何在一个简单的非 Rails 项目中使用特定的 Ruby 版本

ruby 令人敬畏的ActiveRecord错误报告脚本。如何在Ruby脚本中使用ActiveRecord和SQLite。