新手问题 Java 的 3DES 加密在 Ruby 中的实现?

w7938940 · December 22, 2017 · Last by w7938940 replied at January 12, 2018 · 2780 hits

Java 版本

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Base64;

public class Des3Sign {
    private static String ALGORITHM="DESede";

    /**
     * 3DES加密
     * @param src 需要加密的明文
     * @return 加密后的密文
     */
    public static String  DES3EncryptMode(String src) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        DESedeKeySpec desKeySpec = new DESedeKeySpec(ParmaConsts.DES3_KEY.getBytes()); 
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); 
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec); 
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        return new String(Base64.encodeBase64(cipher.doFinal(src.getBytes("UTF-8"))));
    }

    /**
     * 3DES解密
     * @param src 加密后的密文
     * @return 解密后的明文
     */
    public static String  DES3DecryptMode(String src) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        DESedeKeySpec desKeySpec = new DESedeKeySpec(ParmaConsts.DES3_KEY.getBytes()); 
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); 
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec); 
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte [] dd=cipher.doFinal(Base64.decodeBase64(src.getBytes("UTF-8")));
        return new String(dd,"UTF-8");
    }
}

Ruby 版本

require 'base64'
require 'digest'
require 'openssl'

module Des3Encrypt
  def self.cipher(mode, key, iv, data)
    cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').send(mode)
    cipher.key = key
    cipher.iv  = iv if iv

    encrypted = ''
    encrypted << cipher.update(data)
    encrypted << cipher.final
    encrypted
  end

  def self.encrypt(key, iv, data)
    Base64.strict_encode64 cipher(:encrypt, key, iv, data)
  end

  def self.decrypt(key, iv, data)
    cipher(:decrypt, key, iv, Base64.strict_decode64(data))
  end
end

这两种 3DES 加密解密的方式是一样的吗?Java 端无法解密我的 Ruby 端加密的数据,使用的同样的 key,iv 为空

去掉 -CBC 试试,不行就试试 DES-ECB, 再不行看看 OpenSSL::Cipher.ciphers.grep /DES/, 其中大概有一个对的

楼主解决了没,遇到同样的问题。

Reply to glz1992

最后使用的DES-EDE3模式解密成功

Reply to w7938940

我这边加密出来,始终有 '+, =, /' 这些非字母,数字的符号。而 java 端加密出来却只包含字母和数字。请教

Base64.strict_encode64 试试

You need to Sign in before reply, if you don't have an account, please Sign up first.