[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]用CryptoJS进行aes加密,用java解密,CryptoJS AES encryption and Java AES decryption

上一篇:[备忘]ite.remove()导致的性能问题
下一篇:[备忘]Mybatis拦截器(Interceptor)

添加日期:2025/2/11 16:12:12 快速返回   返回列表 阅读90次


<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script>
var encryptedPassword = CryptoJS.AES.encrypt("000", "1234567890123456").toString();
console.log(encryptedPassword);
</script>


结果是这样的:
U2FsdGVkX19QJHtQtYJCGvev0s3Eggyl13/LzFcdpBI=
U2FsdGVkX1/UaLWRr+ljAoLXOyyLdQGC+17hYXj6/bg=
U2FsdGVkX19t23yJoGphohJOoaN5nRwdsJybq1f81No=
每次结果不一样,而且明显长度比在线网站加密结果长。

尝试base64解密,结果类似:Salted__P${P��B����Ă ����W�
说明结果是加盐的,而且是一定格式的。
每次是新的 IV和新的salt,所以每次结果不一样
toString()转换结果为"OpenSSL兼容字符串",
Base64("Salted__" + salt + ciphertext)

所以,CryptoJS进行aes加密的结果,Java里不是简单的AES解密就行的。

找了半天,找到这个,好使,直接复制粘贴。
https://stackoverflow.com/questions/41432896/cryptojs-aes-encryption-and-java-aes-decryption


 /**
     * 密码解密.
     * @param encryptedData
     * @param secretKey
     * @return
     */
    public static String decryptData(String encryptedData, String secretKey)  {
        try {
            byte[] cipherData = Base64Utils.decode(encryptedData);
            byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);

            MessageDigest md5 = MessageDigest.getInstance("MD5");
            final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secretKey.getBytes(StandardCharsets.UTF_8), md5);
            SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
            IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);

            byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
            Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
            aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
            byte[] decryptedData = aesCBC.doFinal(encrypted);
            String decryptedText = new String(decryptedData, StandardCharsets.UTF_8);

            return decryptedText;
        }catch (Exception e){
            return "";
        }
    }

    /**
     * Generates a key and an initialization vector (IV) with the given salt and password.
     * <p>
     * This method is equivalent to OpenSSL's EVP_BytesToKey function
     * (see https://github.com/openssl/openssl/blob/master/crypto/evp/evp_key.c).
     * By default, OpenSSL uses a single iteration, MD5 as the algorithm and UTF-8 encoded password data.
     * </p>
     * @param keyLength the length of the generated key (in bytes)
     * @param ivLength the length of the generated IV (in bytes)
     * @param iterations the number of digestion rounds
     * @param salt the salt data (8 bytes of data or <code>null</code>)
     * @param password the password data (optional)
     * @param md the message digest algorithm to use
     * @return an two-element array with the generated key and IV
     */
    public static byte[][] GenerateKeyAndIV(int keyLength, int ivLength, int iterations, byte[] salt, byte[] password, MessageDigest md) {

        int digestLength = md.getDigestLength();
        int requiredLength = (keyLength + ivLength + digestLength - 1) / digestLength * digestLength;
        byte[] generatedData = new byte[requiredLength];
        int generatedLength = 0;

        try {
            md.reset();

            // Repeat process until sufficient data has been generated
            while (generatedLength < keyLength + ivLength) {

                // Digest data (last digest if available, password data, salt if available)
                if (generatedLength > 0)
                    md.update(generatedData, generatedLength - digestLength, digestLength);
                md.update(password);
                if (salt != null)
                    md.update(salt, 0, 8);
                md.digest(generatedData, generatedLength, digestLength);

                // additional rounds
                for (int i = 1; i < iterations; i++) {
                    md.update(generatedData, generatedLength, digestLength);
                    md.digest(generatedData, generatedLength, digestLength);
                }

                generatedLength += digestLength;
            }

            // Copy key and IV into separate byte arrays
            byte[][] result = new byte[2][];
            result[0] = Arrays.copyOfRange(generatedData, 0, keyLength);
            if (ivLength > 0)
                result[1] = Arrays.copyOfRange(generatedData, keyLength, keyLength + ivLength);

            return result;

        } catch (DigestException e) {
            throw new RuntimeException(e);

        } finally {
            // Clean out temporary data
            Arrays.fill(generatedData, (byte)0);
        }
    }
    public static void main(String[] args) {
        String secretKey = "1234567890123456"; //16字节
        String a = decryptData("U2FsdGVkX1/UaLWRr+ljAoLXOyyLdQGC+17hYXj6/bg=",secretKey);
        System.out.println(a);
    }


 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved