Ruby Ruby 中通过 AES-128-CBC 加密后密码和 Java 中通过 AES/CBC/PKCS5Padding 加密的密码不一致?

liy_j · 2015年05月29日 · 最后由 liy_j 回复于 2015年06月02日 · 11418 次阅读

最近在调试一个加密和解密的接口,用 ruby 加密,然后用 java 解密,在用 java 解密时错误。然后调试中分别用 ruby 和 java 给数据加密,看是否一致,结果发现加密的结果也不一致,大神帮看看是什么原因

data = "45b00417-f7ca-4f53-bced-c1743d85604"

cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
key = "quck7295abvdefgh"
iv = "abcdefgh3762quck"

encrypted = cipher.update(data) + cipher.final
Base64.encode64(encrypted)

使用相同的 key 来加密 ruby 加密后结果为:

双次加密后结果:"EAhESILT2j/MSa1CykE7yqtX7N8XvPVzrzewJoELRuPj+rK8DeSuxROD/uOq\nLqhy\n"

java 加密后结果为:

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class CipherUtil {

    private final static byte[] KEY = "quck7295abvdefgh".getBytes();
    private final static byte[] IV = "abcdefgh3762quck".getBytes();

    public static byte[] encryption(byte[] data) throws Exception {
        return cipherIV(Cipher.ENCRYPT_MODE, data);
    }

    public static byte[] decryption(byte[] data) throws Exception {
        return cipherIV(Cipher.DECRYPT_MODE, data);
    }

    private static byte[] cipherIV(int mode, byte[] data) throws Exception {
        SecretKeySpec sekey = new SecretKeySpec(KEY, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(mode, sekey, new IvParameterSpec(IV));
        byte[] decrypted = cipher.doFinal(data);
        return decrypted;
    }

    private static byte[] cipher(int mode, byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(mode, new SecretKeySpec(KEY, "AES"));
        byte[] decrypted = cipher.doFinal(data);
        return decrypted;
    }

    public static void main(String[] args) throws Exception {
        String str = "45b00417-f7ca-4f53-bced-c1743d85604";
        byte[] b = encryption(str.getBytes());
        String str1 = new String(Base64.encodeToString(b));
        System.out.println(str);
        System.out.println(str1);
        System.out.println(new String(decryption(Base64.decode(str1))));
    }
}
双次加密后:2TStMVj6tPz8m4o0hjSY/GwTfx4UXFfDti9yhiJ6fr2tQFQsfNDG4Mqb3wpNy6x1

还有就是,ruby 加密后所谓的标准填充模式是什么啊?

翻我的贴,有个配置,Java 和 Ruby 默认参数不同,所以有差别

少了步骤了吧:

data = "45b00417-f7ca-4f53-bced-c1743d85604c"
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
key = "quck7295abvdefgh"
iv = "abcdefgh3762quck"
cipher.key = GENERATE_KEY_FROM(key) 
# 其实这里的 key 就是所谓的 password, 根据具体的算法生成 cipher key,比如 pbkdf2
# cipher key 的长度是固定的 AES-CBC-128 的 key 是 16 位, AES-CBC-256 的 key 是 32 位

cipher.iv = IV # 这里可以自定义,也可以用 cipher.random_iv

encrypted = cipher.update(data) + cipher.final

是微信的那个加密解密方案么?好像要设置 padding

cipher = OpenSSL::Cipher::AES.new(256, :CBC)
cipher.encrypt
# must set up padding
cipher.padding = 0
cipher.key     = key
cipher.iv      = key[0...16]
cipher.update(text) + cipher.final

@huacnlee @gihnius @color_huo 多谢各位,现在结贴。

cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
cipher.key = "quck7295abvdefgh"
cipher.iv = "abcdefgh3762quck"
encrypted = cipher.update(uuid) + cipher.final
Base64.strict_encode64(encrypted)

这样改变后,就可以正确的加密了,刚开始,只是设立了 key 和 iv,但是并没有把它赋值给 cipher 比较老的链接,但具有参考意义:http://techmedia-think.hatenablog.com/entry/20110527/1306499951

huacnlee 关闭了讨论 11月25日 10:09
huacnlee [该话题已被删除] 中提及了此贴 11月25日 10:09
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册