<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); }
|