当前位置: 首页 > 知识库问答 >
问题:

Java AES-256 解密 - 从操作脚本 3 转换代码

慕容铭
2023-03-14

我在ActionScript 3中有一个工作解密,现在我想在Java中解密时得到相同的结果。(我知道OFB模式和空填充可能不是首选,但这是我当时使用的,也是我现在需要解密的...)

(非常旧)Adobe ActionScript 3代码:

static public function decryptTest(): Boolean {
    var iv: String = "0df1eff724d50157ab048d9ff214b73c";
    var cryptext: String = "2743be20314cdc768065b794904a0724e64e339ea6b4f13c510e2d2e8c95dd7409aa0aefd20daae80956dd2978c98d6e914d1d7b5b5be47b491d91e7e4f16f7f30d991ba80a81bafd8f0d7d83755ba0ca66d6b208424529c7111bc9cd6d11786f3f604a0715f";
    var kkey: String = "375f22c03371803ca6d36ec42ae1f97541961f7359cf5611bbed399b42c7c0be";

    var kdata: ByteArray = Hex.toArray(kkey);
    var data: ByteArray = Hex.toArray(cryptext);
    var name: String = 'aes-256-ofb';
    var pad:IPad = new NullPad();
    var mode: ICipher = Crypto.getCipher(name, kdata, pad);
    pad.setBlockSize(mode.getBlockSize());
    trace("mode block size: " + mode.getBlockSize());

    if (mode is IVMode) {
        var ivmode:IVMode = mode as IVMode;
        ivmode.IV = Hex.toArray(iv);
    }
    mode.decrypt(data);

    var res: String = data.toString();
    trace("result: " + res);

    return res == "01020506080b10131c22292d313536393b464c535466696d6e7d7f808a8e9899a2adb1b8babcbebfc1c6c7c8cecfd8e0e4e8ef";
}

trace("decryption test: " + netplay.decryptTest());

闪存输出为:

mode block size: 16
result: 01020506080b10131c22292d313536393b464c535466696d6e7d7f808a8e9899a2adb1b8babcbebfc1c6c7c8cecfd8e0e4e8ef
decryption test: true

我试过什么?

我在Java中尝试了两种不同的方法,一种使用内置的< code>Cipher类,另一种使用这个代码/类。然而,第一种方法给了我一个IllegalKeyException,另一种方法给了我垃圾。此外,第二种方法没有明确说明如何输入解密的IV数据,也没有让我指定OFB模式或填充。

java.security.InvalidKeyException: Illegal key size
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1023)
    at javax.crypto.Cipher.implInit(Cipher.java:789)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:848)
    at javax.crypto.Cipher.init(Cipher.java:1347)
    at javax.crypto.Cipher.init(Cipher.java:1281)
    at test.net.zomis.ZomisTest.decryptCipher(ZomisTest.java:112)
@Test
public void decryptCipher() throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
    String iv = "0df1eff724d50157ab048d9ff214b73c";
    String cryptext = "2743be20314cdc768065b794904a0724e64e339ea6b4f13c510e2d2e8c95dd7409aa0aefd20daae80956dd2978c98d6e914d1d7b5b5be47b491d91e7e4f16f7f30d991ba80a81bafd8f0d7d83755ba0ca66d6b208424529c7111bc9cd6d11786f3f604a0715f";
    String key = "375f22c03371803ca6d36ec42ae1f97541961f7359cf5611bbed399b42c7c0be"; // Hexadecimal String, will be converted to non-hexadecimal String
    String expectedResult = "01020506080b10131c22292d313536393b464c535466696d6e7d7f808a8e9899a2adb1b8babcbebfc1c6c7c8cecfd8e0e4e8ef";

    byte[] kdata = Util.hex2byte(key);

    Assert.assertEquals(32, kdata.length); // 32 bytes = 256-bit key

    String result;

    Cipher cipher;
    cipher = Cipher.getInstance("AES/OFB/NoPadding");
    // Below line is 112, which is causing exception
    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(kdata, "AES"), new IvParameterSpec(iv.getBytes("UTF-8")));
    byte[] cryptData = Util.hex2byte(cryptext);
    byte[] ciphertext = cipher.doFinal(cryptData);
    result = new String(ciphertext);


    Assert.assertEquals(expectedResult, result);
}

@Test
public void decryptAES() {
    String iv = "0df1eff724d50157ab048d9ff214b73c"; 
    // Problem: Where should I specify the IV ???? Currently it is an unused variable...

    String cryptext = "2743be20314cdc768065b794904a0724e64e339ea6b4f13c510e2d2e8c95dd7409aa0aefd20daae80956dd2978c98d6e914d1d7b5b5be47b491d91e7e4f16f7f30d991ba80a81bafd8f0d7d83755ba0ca66d6b208424529c7111bc9cd6d11786f3f604a0715f";
    String key = "375f22c03371803ca6d36ec42ae1f97541961f7359cf5611bbed399b42c7c0be"; // Hexadecimal String, will be converted to non-hexadecimal String
    String expectedResult = "01020506080b10131c22292d313536393b464c535466696d6e7d7f808a8e9899a2adb1b8babcbebfc1c6c7c8cecfd8e0e4e8ef";

    Assert.assertEquals(64, key.length());

    AES aes = new AES();
    aes.setKey(Util.hex2byte(key));
    byte[] byteCryptedData = Util.hex2byte(cryptext);
    String byteCryptedString = new String(byteCryptedData);

    while (byteCryptedString.length() % 16 != 0) byteCryptedString += " ";


    String result = aes.Decrypt(byteCryptedString);
    Assert.assertEquals(expectedResult, result); // Assertion Failed
}

问题是:如何让Java像ActionScript 3一样解密?当然,我希望两者的结果相同。

共有2个答案

司徒寒
2023-03-14

是的,有这样的图书馆,看看http://www.bouncycastle.org/吧。这是一个更具体的Java弹力城堡加密系统——用AES加密

闻人伟
2023-03-14

第一种方法是给您一个< code >非法密钥大小错误消息,因为您没有安装无限制的策略文件。如果没有这些,Java将拒绝使用“强”密钥长度(例如256位AES)。

如果这样做在您的司法管辖区是合法的,请通过 Google 搜索“无限强度司法管辖区政策文件”,并下载适用于您的 Java 安装的版本。您最终将获得两个文件,以转储到 JRE 中的库/安全性中。

 类似资料:
  • 我有一个应用程序,需要在配置文件中存储一些秘密密码,如数据库和ftp密码/详细信息。我环顾四周,发现了许多使用AES的加密/解密解决方案,但我似乎不知道如何在不改变密钥的情况下使其工作。这意味着我可以加密和解密(使用相同的秘密密钥),但在重启等过程中保持持久性。我似乎无法让秘密钥匙保持不变。下面的示例显示了我的工作方法: 到目前为止还不错。然而,如果我运行它一次,我可能会得到'2Vhht/L80U

  • 我在这个网站上用AES-256加密一个虚拟字符串: https://www.devglan.com/online-tools/aes-encryption-decryption 具有以下参数: null 当我尝试用OpenSSL从命令行解密它时: 我得到这个错误:

  • 访问 获取子节点的Path 为了得到一个AST节点的属性值,我们一般先访问到该节点,然后利用 path.node.property 方法即可。 // the BinaryExpression AST node has properties: `left`, `right`, `operator` BinaryExpression(path) { path.node.left; path.n

  • 让我们假设我对SHA-256中的所有MD5哈希进行哈希。我会得到md5哈希的sha-256哈希。 附注:我知道重复哈希并不安全,这不是我问题的重点 当用户想要连接时,我只需更改中的,使其与存储在数据库中的值匹配(假设$password是正确的) 这种做法有缺陷吗?

  • 我做了一个简单的文件加密/解密器。它将模式和要操作的文件作为参数。加密时,它生成随机字符串并使用该字符串加密文件。解密文件时,它会提示用户输入密码,并在解密时使用该密码。 我的问题是,解密时得到的不是明文,而是胡言乱语,尽管我小心翼翼地将相同的密钥写入输入。 非常感谢James K Polk提供的加密/解密代码!

  • 这个类别的全部是展示以某些东西为基础来创建 Observables 是多么的容易,因此他们可以和操作符配合的很好,而不在乎是怎样的构造,从而实现丰富的组合。 from 在 RxJS 4中,存在一些类似名称的操作符,例如 fromArray()、from()、fromPromise() 等等。所有这些 fromXXX 的操作符现在全由 from() 接管了。来看一些示例: 老的 fromArray