如何使用Java从CryptoJS解密加密的AES-256字符串?[关闭]

如何使用Java从CryptoJS解密加密的AES-256字符串?[关闭],第1张

如何使用Java从CryptoJS解密加密的AES-256字符串?[关闭]

以这种方式加密消息时:

CryptoJS.AES.encrypt("message", "passphrase")

使用基于密码的方法。为此,CryptoJS生成了一个新的盐,并将该盐与密码短语结合使用以得出密钥和IV(我已经为这个问题编写了派生函数)。
生成密文后,将使用特殊的OpenSSL格式化程序对包含所用盐的密文进行编码:

var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);

您可能需要解码base64编码的字符串以获取字节数组(如果有)。然后,您可以检查标题是否匹配:

byte[] ctBytes = base64.getDeprer().depre(ciphertext.getBytes("UTF-8"));System.out.println("Is salted: " + new String(Arrays.copyOf(ctBytes, 8)).equals("Salted__"));

之后,您可以从中恢复盐和密文:

byte[] saltBytes = Arrays.copyOfRange(ctBytes, 8, 16);byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);

导出键+ IV:

byte[] key = new byte[keySize/8];byte[] iv = new byte[ivSize/8];EvpKDF(password.getBytes("UTF-8"), keySize, ivSize, saltBytes, key, iv);

并解密密文:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),        new IvParameterSpec(iv));byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);String recoveredPlaintext = new String(recoveredPlaintextBytes);

完整的完整代码:

public static void main(String[] args) throws UnsupportedEncodingException, GeneralSecurityException {    String ciphertext = "U2FsdGVkX1+0m/gle/XQX1shjnpveUrl1fO3oOlurPMlTks6+oQlEPfOrucihzEz";    String plaintext = "This is some example plaintext";    String password = "This is a very strong password";    int keySize = 256;    int ivSize = 128;    // var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);    byte[] ctBytes = base64.getDeprer().depre(ciphertext.getBytes("UTF-8"));    System.out.println("Is salted: " + Arrays.equals(Arrays.copyOf(ctBytes, 8), new byte[]{0x53, 0x61, 0x6c, 0x74, 0x65, 0x64, 0x5f, 0x5f}));    System.out.println("Is salted: " + new String(Arrays.copyOf(ctBytes, 8)).equals("Salted__"));    byte[] saltBytes = Arrays.copyOfRange(ctBytes, 8, 16);    System.out.println("Salt matches: " + Arrays.equals(saltBytes, hexStringToByteArray("b49bf8257bf5d05f")));    byte[] ciphertextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.length);    System.out.println("CT matches: " + Arrays.equals(ciphertextBytes, hexStringToByteArray("5b218e7a6f794ae5d5f3b7a0e96eacf3254e4b3afa842510f7ceaee722873133")));    byte[] key = new byte[keySize/8];    byte[] iv = new byte[ivSize/8];    EvpKDF(password.getBytes("UTF-8"), keySize, ivSize, saltBytes, key, iv);    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");    cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));    byte[] recoveredPlaintextBytes = cipher.doFinal(ciphertextBytes);    String recoveredPlaintext = new String(recoveredPlaintextBytes);    System.out.println("Recovered Plaintext: " + recoveredPlaintext);    System.out.println("Expected Plaintext: " + plaintext);}public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {    return EvpKDF(password, keySize, ivSize, salt, 1, "MD5", resultKey, resultIv);}public static byte[] EvpKDF(byte[] password, int keySize, int ivSize, byte[] salt, int iterations, String hashAlgorithm, byte[] resultKey, byte[] resultIv) throws NoSuchAlgorithmException {    keySize = keySize / 32;    ivSize = ivSize / 32;    int targetKeySize = keySize + ivSize;    byte[] derivedBytes = new byte[targetKeySize * 4];    int numberOfDerivedWords = 0;    byte[] block = null;    MessageDigest hasher = MessageDigest.getInstance(hashAlgorithm);    while (numberOfDerivedWords < targetKeySize) {        if (block != null) { hasher.update(block);        }        hasher.update(password);        block = hasher.digest(salt);        hasher.reset();        // Iterations        for (int i = 1; i < iterations; i++) { block = hasher.digest(block); hasher.reset();        }        System.arraycopy(block, 0, derivedBytes, numberOfDerivedWords * 4,     Math.min(block.length, (targetKeySize - numberOfDerivedWords) * 4));        numberOfDerivedWords += block.length/4;    }    System.arraycopy(derivedBytes, 0, resultKey, 0, keySize * 4);    System.arraycopy(derivedBytes, keySize * 4, resultIv, 0, ivSize * 4);    return derivedBytes; // key + iv}public static byte[] hexStringToByteArray(String s) {    int len = s.length();    byte[] data = new byte[len / 2];    for (int i = 0; i < len; i += 2) {        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)     + Character.digit(s.charAt(i+1), 16));    }    return data;}

Javascript代码:

var pw = "This is a very strong password";var pt = "This is some example plaintext";var encrypted = CryptoJS.AES.encrypt(pt, pw);encrypted.toString(); // U2FsdGVkX1+0m/gle/XQX1shjnpveUrl1fO3oOlurPMlTks6+oQlEPfOrucihzEzencrypted.salt.toString(); // b49bf8257bf5d05fencrypted.ciphertext.toString(); // 5b218e7a6f794ae5d5f3b7a0e96eacf3254e4b3afa842510f7ceaee722873133


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4974846.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-14
下一篇 2022-11-14

发表评论

登录后才能评论

评论列表(0条)

保存