将旧的AES 256加密从Java重新编码到Ruby

将旧的AES 256加密从Java重新编码到Ruby,java,ruby,encryption,aes,Java,Ruby,Encryption,Aes,我正在尝试将Java中完成的旧加密/解密复制到Ruby one中的新加密/解密,因为我正在重建整个应用程序。显然,所有这些都是为了尽快更改加密 以下是Java代码: public class MyClass { private static String algo; private static SecretKey key; static { algo = "AES"; String keyString = "someString";

我正在尝试将Java中完成的旧加密/解密复制到Ruby one中的新加密/解密,因为我正在重建整个应用程序。显然,所有这些都是为了尽快更改加密

以下是Java代码:

public class MyClass {
    private static String algo;
    private static SecretKey key;

    static {
        algo = "AES";
        String keyString = "someString";

        byte[] decodedKey = Base64.getDecoder().decode(keyString);
        key = new SecretKeySpec(decodedKey, 0, decodedKey.length, algo);
    }

    private static String decrypt(String encrypted) {
        try {
            Cipher cipher = Cipher.getInstance(algo);
            cipher.init(Cipher.DECRYPT_MODE, key);

            byte[] decodedBytes = Base64.getDecoder().decode(encrypted.getBytes());
            byte[] original = cipher.doFinal(decodedBytes);

            return new String(original);
        }
        catch (Exception e) {
            // Some error
            return "bad";
        }
    }

    private static String encrypt(String toEncrypt) {
        try {
            Cipher cipher = Cipher.getInstance(algo);
            cipher.init(Cipher.ENCRYPT_MODE, key);

            byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
            byte[] encryptedValue = Base64.getEncoder().encode(encrypted);

            return new String(encryptedValue);
        }
        catch (Exception e) {
            // Some error
            return "bad";
        }
    }
}
Java代码来自

我对解密有问题。以下是我的Ruby代码:

key = Digest::SHA256.digest(key)
aes = OpenSSL::Cipher.new('AES-256-CBC')
aes.decrypt
aes.key = Digest::SHA256.digest(key)
aes.update(secretdata) + aes.final

# => OpenSSL::Cipher::CipherError: bad decrypt

我做错了什么?

这并不是那么容易,但这是我的方法

class ManualEncryption
  class << self
    attr_accessor :configuration

    def config
      @configuration ||= Configuration.new
    end

    def aes
      return @aes if @aes
      @aes = OpenSSL::Cipher.new(config.algo) # "AES-256-ECB"
      @aes
    end

    def decodedKey
      return @decodedKey if @decodedKey
      @decodedKey = Base64.decode64(config.key_string) # "mySecretString"
    end

    def configure
      yield(config)
      raise 'Algo not specified' unless config.algo
      raise 'key not specified' unless config.key_string
    end

    def encrypt(value)
      raise 'No configuration done' unless config.algo && config.key_string
      aes_perform('encrypt', value)
    end

    def decrypt(value)
      raise 'No configuration done' unless config.algo && config.key_string
      return value unless value
      aes_perform('decrypt', value)
    end

    def aes_perform(status, value)
      aes.reset
      if status.eql?('encrypt')
        aes.encrypt
        aes.key = decodedKey
        aes_val = aes.update(value) + aes.final
        Base64::encode64(aes_val)
      else
        aes.decrypt
        aes.key = decodedKey
        decoded_value = Base64::decode64(value)
        aes.update(decoded_value) + aes.final
      end
    end
  end

  class Configuration
    attr_accessor :algo, :key_string
    attr_reader :aes
  end
end

注意:我仍然有一个加密问题。它在我的加密值中创建\n,我不知道为什么。我正在研究它。

AES算法描述不完整;它将使用默认的操作模式和填充方案。在JRE中包含的提供程序中,这将默认为ECB和PKCS7 padding AES/ECB/PKCS5Padding。这显然是不安全的,因为欧洲央行是不安全的,但由于依赖于该违约的应用程序,它无法更改,这也是违约最初是错误的原因之一

此外,在您提供的代码中不涉及哈希。这是一件好事,因为密钥上的单个安全哈希不足以提供良好的安全性。将密钥存储在字符串中几乎同样糟糕,但并不完全如此。然而,密钥是以64进制编码的


因此,您必须切换到“AES-256-ECB”并删除密钥的双哈希,代之以base 64解码。

该密钥隐式使用ECB模式,并且它没有收到6次无意义的否决票。投票结果可能来自那些故意复制安全相关代码的人。就像你现在所做的一样。@MaartenBodewes我刚刚接受了这个代码。不是我送的。我只是想弄明白我不懂的神奇部分是什么。我知道这种加密是不可用的,以前的开发人员也不知道他在做什么。但我现在一直在使用这种语言和加密技术。第一步是在一个更友好、可用的加密中复制加密。第二件事是改变它。好的,如果是那样的话,我一定会试试AES-256-ECB。ECB是AES密码的不安全默认值-无论如何,对于Sun/Oracle提供程序。对于所有其他模式,如CBC或GCM,您需要静脉注射。可能是因为您对密钥进行了两次哈希运算?如果没有确切的Java代码,我们无法判断。在创建问题时,您确实应该更加小心。现在您已经省略了类和构造函数,而这正是确定algo和key的地方。这就是为什么创建MCVE如此重要的原因。