java - AES 算法 Java/Java Script 中的 128 位 key 问题

标签 java javascript encryption

我需要使用用户选择 key 加密 Java 代码中的值,并解密 Java 脚本模块中的值。

下面是我用于加密值的 Java 代码。在这里,我从用户选择 key 生成 128 位 key 值,并使用相同的方法来加密这些值。

String plainText = "Hello, World! This is a Java/Javascript AES test.";
        try {
            byte[] rawKey = getRawKey("12345".getBytes());
            SecretKey key = new SecretKeySpec(rawKey, "AES");

            AlgorithmParameterSpec iv = new IvParameterSpec(
                    Base64.decodeBase64("5D9r9ZVzEYYgha93/aUK2w=="));

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, iv);
            System.out.println(Base64.encodeBase64String(cipher
                    .doFinal(plainText.getBytes("UTF-8"))));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Exception in crypto...");
        }

public static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        String s = new String(raw);
        System.out.println("raw key.." + raw);
        return raw;
    }

上面的代码打印以下值:

raw key..[B@45b9ce4b
vN2GouJcVli/rFMDHEwCNZejraO5cQxBtlo5D64qkaRTkxxRTIo+Vm38H4fUZp7ABxj7ul0Ha6bO5aFxMzMY0g==

当我使用上述值在 JS 代码中解密时,我没有得到任何响应。

<html>
<head> 

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script >
var encrypted = CryptoJS.enc.Base64.parse('vN2GouJcVli/rFMDHEwCNZejraO5cQxBtlo5D64qkaRTkxxRTIo+Vm38H4fUZp7ABxj7ul0Ha6bO5aFxMzMY0g==');
var key = CryptoJS.enc.Base64.parse('[B@45b9ce4b');
var iv = CryptoJS.enc.Base64.parse('5D9r9ZVzEYYgha93/aUK2w==');
document.write(CryptoJS.enc.Utf8.stringify(CryptoJS.AES.decrypt(
    { ciphertext: encrypted },
    key, 
    { mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, iv: iv,  })));
</script>
</head>
<body>

<h1>hsd h </h1>

</body>
</html>

如果我的代码中缺少任何内容,请指出我,或者请建议我是否有任何替代方法可以产生相同的结果。

最佳答案

您的 JS 代码中的 key 不正确。在您的 Java 代码中,您使用 byte[] 作为参数调用 System.out.println(),这不会为您提供有意义的输出。 [B@45b9ce4b 不是有效的 Base64 数据。

要解决此问题,您需要获取表示 key 的 byte[] 并将其 Base64 编码为字符串,然后打印该字符串。

对 key 生成的评论:

您应该避免使用随机数生成器从用户输入(即密码)中派生 key Material 。根据用户输入创建 key Material 的正确方法是使用 key 拉伸(stretch)算法。

您绝对应该为此使用标准算法,例如 PBKDF2 。在 Java 中,您可以通过 SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

获取 key 工厂

关于java - AES 算法 Java/Java Script 中的 128 位 key 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23371389/

相关文章:

java - java中有没有用于单位转换的库?

java - 最佳实践 : how do I tell if a collection/set/let is a Guava ImmutableSet/Immutable map?

javascript - 如何在 "ios contenteditable element"中格式化文本后恢复平滑滚动?

javascript - 当计数器有某个值时如何触发事件?

java - Spring Batch 多步骤与单步骤

java - 父类返回子类

javascript - 如果我们将对象的属性分配给另一个变量然后使用它,是否会影响代码的速度效率?

react-native - 在react-native中使用加密数据库

ios - 为什么 NSFileProtectionComplete 不起作用?

git - git history 是否会破坏使用 OpenSSL 加密的文件?