为什么 Java 无法解密 CryptoJS 加密数据?

huangapple go评论71阅读模式
英文:

Why can't java decrypt CryptoJS encrypted data?

问题

以下是已翻译的内容:

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

aesEncrypt('Test', 'o9szYIOq1rRMiouNhNvaq96lqUvCekxR');

当我向Java API发送请求时,我收到以下错误:

Given final block not properly padded. Such issues can arise if a bad key is used during decryption.

我甚至尝试了使用Forge库,但也不起作用,代码如下:

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

我注意到两者之间的区别,来自于Forge的部分,当我输出数据,即 console.log(cipher.output.data),我得到了一大串数据。然而,从CryptoJS获得的输出却是 console.log(ciphertext),得到了另一组数据。

如何使用其中之一?为什么会有上述输出之间的差异?

英文:

I have function for decrypting in Java as such

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

I tried to encrypt the data using CryptoJS as such

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

When I send the request to JAVA API I get

> Given final block not properly padded. Such issues can arise if a bad
> key is used during decryption

I even tried with forge library. It does not work either.

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

The difference I see between the two is from forge, when I output the data i.e console.log(cipher.output.data) . I get

> uJ­@^$¿EÅKÖé1ÙN¢cÖúp†‡xÇÅÂëv‹‹¥qè9Ï/¨§È5æý»¸,À‰¿ "y§¯:ßñ[®†ÓjÃùØQèóŒ÷‘à¯~6j˜Ø¿óðn5–»™ˆ§Ñ
> ,A.ÛC‚eðša’“©ëZÁR¸Ž:­jy¹S–cÃ6‚d#ÚÔí\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°»y’NûöCpã

But from CryptoJS I get console.log(ciphertext)

> ad423bc873ca1cc2f228c7158ccf95e67eae4029d5a2e9fbad42e7be7bcad23fcfb94217b90a84c4e6e9786d36edd337615c392a4d260dd68fb6bf45032a31fc6eec99a8f9b5e8efa6e5f2fe2a2b1e68e3a6a57cee0f12d42ff66c986d45da825398213361de9f448b7db0b8a38c79091519105b7c12a4d19998de8e0fb211d81fa1b3d1801d5c8eba907e7aacfa891fa7872e951ee645840e86699c93e98a355ea0f6331889663326f88f0d09b7a6245bd52443f98e6bb274edda32b7135e17d342db77759099688a14ac5edddc7c760e179ad4ad08d9d1fd3b11f1c96be0804c74bf9a9032d07af12e60a76dfddf28984901485e032b33e19db8332a8b49244c9c46081d13c6c632c8792c318a5cc8a7aa4612a76d0b6413367c248b3c0c6e53f301601b0f1bea6ee2b0b5344c445a1da32274c63e81f94dff3db98aae6348c936a2bbac6a3912595c981349556f161d12c843e516aadf95c8ab6be3aaa49d382e5af074575777e8d96964c2fd7a4cad03dd2a9137d8b4ffd85eaaabdd0f86

How to use either of the two? and Why is there a difference between the above output?

答案1

得分: 3

以下是你提供的代码的翻译部分:

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

明文:Test
密文:oNP8t53ZTi1WUptGCDh5NQ==
解密后的文本:Test

Java输出:

来自Javascript的密文:oNP8t53ZTi1WUptGCDh5NQ==
解密:Test

Javascript代码:

// *** 安全警告 ***
// 请勿在生产环境中使用此代码,因为它是不安全的
// 它使用了ECB模式和静态密钥

var 明文 = 'Test';
console.log('明文:', 明文);

/**
 * 加密
 * @param word
 * @returns {*}
 */
function 加密(word){
    const keyBase64 = "o9szYIOq1rRMiouNhNvaq96lqUvCekxR";
    var key = CryptoJS.enc.Base64.parse(keyBase64);
    var srcs = CryptoJS.enc.Utf8.parse(word);
    var 加密结果 = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
    return 加密结果.toString();
}
 
/**
   * 解密
 * @param word
 * @returns {*}
 */
function 解密(word){
    const keyBase64 = "o9szYIOq1rRMiouNhNvaq96lqUvCekxR";
    var key = CryptoJS.enc.Base64.parse(keyBase64);
    var 解密结果 = CryptoJS.AES.decrypt(word, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
    return CryptoJS.enc.Utf8.stringify(解密结果).toString();
}

var 密文 = 加密(明文);
console.log('密文:', 密文);
var 解密后的文本 = 解密(密文);
console.log('解密后的文本:', 解密后的文本);

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("为什么Java不能解密CryptoJS加密的数据?");
        String 来自Javascript的密文 = "oNP8t53ZTi1WUptGCDh5NQ==";
        System.out.println("来自Javascript的密文:" + 来自Javascript的密文);
        System.out.println("解密:" + 解密(来自Javascript的密文));
    }
    public static String 解密(String 密文) throws Exception {
        SecretKey 密钥 = 获取密钥("o9szYIOq1rRMiouNhNvaq96lqUvCekxR");
        Cipher 密码器 = Cipher.getInstance("AES/ECB/PKCS5Padding");
        密码器.init(Cipher.DECRYPT_MODE, 密钥);
        return new String(密码器.doFinal(Base64.getDecoder().decode(密文)));
    }

    public static SecretKey 获取密钥(String 密钥) throws Exception {
        byte[] 解码后的密钥 = Base64.getDecoder().decode(密钥);
        return new SecretKeySpec(解码后的密钥, 0, 解码后的密钥.length, "AES");
    }
}
英文:

Please find below a code pair that uses Javascript to en- and decrypt a string with static key in ECB mode. The Java code
is taking the ciphertext (= output of encryption function) from Javascript and decrypts the Base64 encoded ciphertext.

Security warning: Both codes are UNSECURE as they use the ECB mode and static encryption key.

Javascript output (see live example with this link: https://playcode.io/682378)

plaintext: Test
ciphertext: oNP8t53ZTi1WUptGCDh5NQ==
decryptedtext: Test

Java output:

ciphertextFromJavascript: oNP8t53ZTi1WUptGCDh5NQ==
decrypted: Test

Javascript code:

// *** 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 code:

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

答案2

得分: 0

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");
}
英文:

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

huangapple
  • 本文由 发表于 2020年9月30日 02:13:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/64125317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定