【问题标题】:Why can't java decrypt CryptoJS encrypted data?java为什么不能解密CryptoJS加密数据?
【发布时间】:2020-09-29 18:13:17
【问题描述】:

我有这样的Java解密功能

public String decrypt() throws Exception {
        SecretKey secretKey = getSecretKey("o9szYIOq1rRMiouNhNvaq96lqUvCekxR");

        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        return new String(cipher.doFinal(base64Decode("ASDASDADS")));
    }

public SecretKey getSecretKey(String secretKey) throws Exception {
        byte[] decodeSecretKey = base64Decode(secretKey);
        return new SecretKeySpec(decodeSecretKey, 0, decodeSecretKey.length, "AES");
    }

我尝试使用 CryptoJS 加密数据

  function aesEncrypt(data, secretKey) {
    var encrypted = CryptoJS.AES.encrypt(data, secretKey, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
    });

    var ciphertext = encrypted.ciphertext.toString();

    var wordArray = CryptoJS.enc.Utf8.parse(ciphertext);
    var base64 = CryptoJS.enc.Base64.stringify(wordArray);
    return base64
  }
  //call the function
  aesEncrypt('Test' , 'o9szYIOq1rRMiouNhNvaq96lqUvCekxR');

当我向 JAVA API 发送请求时,我得到了

给定的最终块未正确填充。如果一个坏的可能会出现这样的问题 解密时使用密钥

我什至尝试过使用伪造库。它也不起作用。

function aesEncrypt(data, secretKey) {
    var cipher = forge.cipher.createCipher('AES-ECB', secretKey)

    cipher.start()
    cipher.update(forge.util.createBuffer(data))
    cipher.finish()

    return forge.util.encode64(cipher.output.data)
  }

我看到两者之间的区别来自伪造,当我输出数据时,即 console.log(cipher.output.data) 。我明白了

uJ@^$¿EÅKÖé1ÙN¢cÖúpxÇÅÂëv¥qè9Ï/¨§È5æý»¸,À¿ "y§¯:ßñ[®ÓjÃùØQèó÷à¯~6jØ¿óðn5»§Ñ ,A.ÛCeða©ëZÁR¸:­jy¹ScÃ6d#ÚÔí\N¤s~ã¯ÃÉ5d0U:©ªÕ"ã¾xx §F?ØïÅFÛbÒÓJ§j¸²ä2½]Õç£ÿ#È&C!M¡ è ÁÖÈ ¾¦aÒc~:°j>yc6ÞÖú]OAÅÖ!x ìJu2ðΡ¦*õô±¤kÆÂTùû=|2^XAy5¹Êè?díXÝg ëq" %üSyÿO¾bzjc²·á­kÑî¼¾¡ÓV*Çr¢rÎlòz°»yNûöCpã

但从 CryptoJS 我得到 console.log(ciphertext)

ad423bc873ca1cc2f228c7158ccf95e67eae4029d5a2e9fbad42e7be7bcad23fcfb94217b90a84c4e6e9786d36edd337615c392a4d260dd68fb6bf45032a31fc6eec99a8f9b5e8efa6e5f2fe2a2b1e68e3a6a57cee0f12d42ff66c986d45da825398213361de9f448b7db0b8a38c79091519105b7c12a4d19998de8e0fb211d81fa1b3d1801d5c8eba907e7aacfa891fa7872e951ee645840e86699c93e98a355ea0f6331889663326f88f0d09b7a6245bd52443f98e6bb274edda32b7135e17d342db77759099688a14ac5edddc7c760e179ad4ad08d9d1fd3b11f1c96be0804c74bf9a9032d07af12e60a76dfddf28984901485e032b33e19db8332a8b49244c9c46081d13c6c632c8792c318a5cc8a7aa4612a76d0b6413367c248b3c0c6e53f301601b0f1bea6ee2b0b5344c445a1da32274c63e81f94dff3db98aae6348c936a2bbac6a3912595c981349556f161d12c843e516aadf95c8ab6be3aaa49d382e5af074575777e8d96964c2fd7a4cad03dd2a9137d8b4ffd85eaaabdd0f86 P>

如何使用两者中的任何一个?以及为什么上面的输出有区别?

【问题讨论】:

    标签: javascript java cryptography aes cryptojs


    【解决方案1】:

    请在下面找到使用 Javascript 在 ECB 模式下使用静态密钥加密和解密字符串的代码对。 Java 代码 正在从 Javascript 中获取密文(= 加密函数的输出)并解密 Base64 编码的密文。

    安全警告:这两个代码都是不安全的,因为它们使用 ECB 模式和静态加密密钥。

    Javascript 输出(通过此链接查看实时示例:https://playcode.io/682378

    plaintext: Test
    ciphertext: oNP8t53ZTi1WUptGCDh5NQ==
    decryptedtext: Test
    

    Java 输出:

    ciphertextFromJavascript: oNP8t53ZTi1WUptGCDh5NQ==
    decrypted: Test
    

    Javascript 代码:

    // *** Security warning **
    // DO NOT USE THIS CODE IN PRODUCTION AS IT IS UNSECURE
    // it uses ECB mode and static key
    
    var plaintext = 'Test';
    console.log('plaintext: ', plaintext);
    
    /**
     * Encryption
     * @param word
     * @returns {*}
     */
    function encrypt(word){
        const keyBase64 = "o9szYIOq1rRMiouNhNvaq96lqUvCekxR";
        var key = CryptoJS.enc.Base64.parse(keyBase64);
        var srcs = CryptoJS.enc.Utf8.parse(word);
        var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
        return encrypted.toString();
    }
     
    /**
       * Decrypt
     * @param word
     * @returns {*}
     */
    function decrypt(word){
        const keyBase64 = "o9szYIOq1rRMiouNhNvaq96lqUvCekxR";
        var key = CryptoJS.enc.Base64.parse(keyBase64);
        var decrypt = CryptoJS.AES.decrypt(word, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
        return CryptoJS.enc.Utf8.stringify(decrypt).toString();
    }
    
    var ciphertext = encrypt(plaintext);
    console.log('ciphertext: ', ciphertext);
    var decryptedtext = decrypt(ciphertext);
    console.log('decryptedtext: ', decryptedtext);
    

    Java 代码:

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.util.Base64;
    
    public class Main {
        public static void main(String[] args) throws Exception {
            System.out.println("Why can't java decrypt CryptoJS encrypted data ?");
            String ciphertextFromJavascript = "oNP8t53ZTi1WUptGCDh5NQ==";
            System.out.println("ciphertextFromJavascript: " + ciphertextFromJavascript);
            System.out.println("decrypted: " + decrypt(ciphertextFromJavascript));
        }
        public static String decrypt(String ciphertext) throws Exception {
            SecretKey secretKey = getSecretKey("o9szYIOq1rRMiouNhNvaq96lqUvCekxR");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)));
            //return new String(cipher.doFinal(base64Decode("ASDASDADS")));
        }
    
        public static SecretKey getSecretKey(String secretKey) throws Exception {
            byte[] decodeSecretKey = Base64.getDecoder().decode(secretKey);
            //byte[] decodeSecretKey = base64Decode(secretKey);
            return new SecretKeySpec(decodeSecretKey, 0, decodeSecretKey.length, "AES");
        }
    }
    

    【讨论】:

    • @Micharel 我想问,你为什么将这个词解析为 UTF-8 。而且我还认为我们必须对生成的加密字符串进行 base64 编码
    • CryptoJs 需要一个词对象作为加密/解密函数的输入。加密的标准输出已经是 Base64 编码的 :-)
    【解决方案2】:

    JavaScript

    encryptMethod(word){
    const keyBase64 = "o9szYIOq1rRMiouNhNvaq96lqUvCekxR";
    var key = CryptoJS.enc.Base64.parse(keyBase64);
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
    return encrypted.toString();}
    

    Java

    public String decriptMethod(String text) throws Exception {
        String ciphertextFromJavascript = text;
        return decrypt(ciphertextFromJavascript);
    }
    public static String decrypt(String ciphertext) throws Exception {
        SecretKey secretKey = getKey("o9szYIOq1rRMiouNhNvaq96lqUvCekxR");
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)));
        //return new String(cipher.doFinal(base64Decode("ASDASDADS")));
    }
    
    public static SecretKey getKey(String secretKey) throws Exception {
        byte[] decodeSecretKey = Base64.getDecoder().decode(secretKey);
        return new SecretKeySpec(decodeSecretKey, 0, decodeSecretKey.length, "AES");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 1970-01-01
      • 2013-07-20
      • 1970-01-01
      相关资源
      最近更新 更多