CryptoJS AES加密和JAVA AES解密值不匹配 [英] CryptoJS AES encryption and JAVA AES decryption value mismatch

查看:285
本文介绍了CryptoJS AES加密和JAVA AES解密值不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用客户端的CryptoJS AES算法对文本进行加密,并且我在java中的服务器端解密它,我得到例外。



JS代码

  var encrypted = CryptoJS.AES.encrypt(Message,Secret Passphrase) ; 
console.info(encrypted+ encrypted);
var decryptpted = CryptoJS.AES.decrypt(encrypted,Secret Passphrase);
var plainText = decryptpted.toString(CryptoJS.enc.Utf8)
console.info(decryptpted+ plainText);

js输出:

 加密U2FsdGVkX1 / uYgVsNZmpbgKQJ8KD + 8R8yyYn5 + irhoI = 
解密消息

Java代码

  import java.nio.charset.Charset; 
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.regex.Pattern;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESJavaScript {
private SecretKeySpec key;
私密密码;
private int size = 128;
private static final Charset CHARSET = Charset.forName(UTF-8);

public AESJavaScript()throws NoSuchAlgorithmException,
NoSuchPaddingException,NoSuchProviderException {
KeyGenerator kgen = KeyGenerator.getInstance(AES);
kgen.init(size); // 192和256位可能不可用
SecretKey skey = kgen.generateKey();
byte [] raw = skey.getEncoded();
key = new SecretKeySpec(raw,AES / CTR / NoPadding);
cipher = Cipher.getInstance(AES / CTR / NoPadding);
}

public void setKey(String keyText){
byte [] bText = new byte [size];
bText = keyText.getBytes(CHARSET);
key = new SecretKeySpec(bText,AES / CTR / NoPadding);
}

public String encrypt(String message)throws InvalidKeyException,
IllegalBlockSizeException,BadPaddingException {
cipher.init(Cipher.ENCRYPT_MODE,key);
byte [] encrypted = cipher.doFinal(message.getBytes());
return byteArrayToHexString(encrypted);
}

public String decrypt(String hexCiphertext)
throws IllegalBlockSizeException,BadPaddingException,
InvalidKeyException {
cipher.init(Cipher.DECRYPT_MODE,key);
byte [] decryptpted = cipher.doFinal(hexStringToByteArray(hexCiphertext));
返回byteArrayToHexString(解密);
}

private static String byteArrayToHexString(byte [] raw){
String hex =0x;
String s = new String(raw); (int x = 0; x< s.length(); x ++){
char [] t = s.substring(x,x + 1).toCharArray();
hex + = Integer.toHexString((int)t [0])。toUpperCase();
}
返回十六进制;
}

private static byte [] hexStringToByteArray(String hex){
模式替换= Pattern.compile(^ 0x);
String s = replace.matcher(hex).replaceAll();

byte [] b = new byte [s.length()/ 2]; (int i = 0; i< b.length; i ++){
int index = i * 2;

int v = Integer.parseInt(s.substring(index,index + 2),16);
b [i] =(byte)v;
}
return b;
}

public static void main(String [] args){
try {
AESJavaScript ajs = new AESJavaScript();
ajs.setKey(Secret Passphrase);
String hexCiphertext =U2FsdGVkX1 / uYgVsNZmpbgKQJ8KD + 8R8yyYn5 + irhoI =;
字符串解密= ajs.decrypt(hexCiphertext);
System.out.println(decryptpted>+解密);
} catch(Exception e){
e.printStackTrace();
}
}

}

异常是:

  java.security.InvalidKeyException:无效的AES密钥长度:17个字节
在com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:372)
javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
javax.crypto.Cipher.checkCryptoPerm( Cipher.java:1010)
在javax.crypto.Cipher.implInit(Cipher.java:786)
在javax.crypto.Cipher.chooseProvider(Cipher.java:849)
在javax .crypto.Cipher.init(Cipher.java:1213)
在javax.crypto.Cipher.init(Cipher.java:1153)
在com.test.jenkins.jenkinsRestart.AESJavaScript.decrypt(AESJavaScript .java:49)
at com.test.jenkins.jenkinsRestart.AESJavaScript.main(AESJavaScript.java:82)

有没有什么我在这里做错了,还有其他简单的方法来做这些加密和解密?

解决方案

您的Java代码充满了错误。以下是其中的一些:




  • 您的初始异常是由于您的密码密码 / code> string包含17个字节。您需要将其截断为16个字节(或将其填充为24或32个字节)。您需要匹配CryptoJS库的行为。


  • 您正在尝试对显示为base64编码的数据进行十六进制解码。尝试使用 DatatypeConverter.parseBase64Binary(hex);


  • 您正在使用算法创建一个秘密密钥 AES / CTR / NoPadding。这是无效的,只需使用AES


  • 您必须将IV /你的解密:

      cipher.init(Cipher.DECRYPT_MODE,key,new IvParameterSpec(...)); 

    您使用的值将取决于CryptoJS正在做什么。也许它使用全零?也许它产生一个随机的,你需要用密文存储?




这应该足以让你开始了。


I am encrypting a text using CryptoJS AES algorithm on the client side and I am decrypting It on Server side in java, I am getting the exception.

JS code :

var encrypted = CryptoJS.AES.encrypt("Message", "Secret Passphrase");
console.info("encrypted " + encrypted);
var decrypted = CryptoJS.AES.decrypt(encrypted, "Secret Passphrase");
var plainText = decrypted.toString(CryptoJS.enc.Utf8)
console.info("decrypted " + plainText);

js output :

encrypted U2FsdGVkX1/uYgVsNZmpbgKQJ8KD+8R8yyYn5+irhoI=
decrypted Message

Java Code :

import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.regex.Pattern;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESJavaScript {
    private SecretKeySpec key;
    private Cipher cipher;
    private int size = 128;
    private static final Charset CHARSET = Charset.forName("UTF-8"); 

    public AESJavaScript() throws NoSuchAlgorithmException,
            NoSuchPaddingException, NoSuchProviderException {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        kgen.init(size); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        key = new SecretKeySpec(raw, "AES/CTR/NoPadding");
        cipher = Cipher.getInstance("AES/CTR/NoPadding");
    }

    public void setKey(String keyText) {
        byte[] bText = new byte[size];
        bText = keyText.getBytes(CHARSET);
        key = new SecretKeySpec(bText, "AES/CTR/NoPadding");
    }

    public String encrypt(String message) throws InvalidKeyException,
            IllegalBlockSizeException, BadPaddingException {
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encrypted = cipher.doFinal(message.getBytes());
        return byteArrayToHexString(encrypted);
    }

    public String decrypt(String hexCiphertext)
            throws IllegalBlockSizeException, BadPaddingException,
            InvalidKeyException {
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decrypted = cipher.doFinal(hexStringToByteArray(hexCiphertext));
        return byteArrayToHexString(decrypted);
    }

    private static String byteArrayToHexString(byte[] raw) {
        String hex = "0x";
        String s = new String(raw);
        for (int x = 0; x < s.length(); x++) {
            char[] t = s.substring(x, x + 1).toCharArray();
            hex += Integer.toHexString((int) t[0]).toUpperCase();
        }
        return hex;
    }

    private static byte[] hexStringToByteArray(String hex) {
        Pattern replace = Pattern.compile("^0x");
        String s = replace.matcher(hex).replaceAll("");

        byte[] b = new byte[s.length() / 2];
        for (int i = 0; i < b.length; i++) {
            int index = i * 2;
            int v = Integer.parseInt(s.substring(index, index + 2), 16);
            b[i] = (byte) v;
        }
        return b;
    }

    public static void main(String[] args) {
        try {
            AESJavaScript ajs = new AESJavaScript();
            ajs.setKey("Secret Passphrase");
            String hexCiphertext = "U2FsdGVkX1/uYgVsNZmpbgKQJ8KD+8R8yyYn5+irhoI=";
            String decrypted = ajs.decrypt(hexCiphertext);
            System.out.println("decrypted > " + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

Exception is :

java.security.InvalidKeyException: Invalid AES key length: 17 bytes
    at com.sun.crypto.provider.AESCipher.engineGetKeySize(AESCipher.java:372)
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1010)
    at javax.crypto.Cipher.implInit(Cipher.java:786)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
    at javax.crypto.Cipher.init(Cipher.java:1213)
    at javax.crypto.Cipher.init(Cipher.java:1153)
    at com.test.jenkins.jenkinsRestart.AESJavaScript.decrypt(AESJavaScript.java:49)
    at com.test.jenkins.jenkinsRestart.AESJavaScript.main(AESJavaScript.java:82)

Is there anything that I am doing wrong here or Is there anyother simple way to do these kind of encryption and decryption ?

解决方案

Your Java code is riddled with errors. Here are a few of them:

  • Your initial exception is caused because your "Secret Passphrase" string contains 17 bytes. You need to truncate this to 16 bytes (or pad it to match 24 or 32 bytes). You need to match the behaviour of the CryptoJS library.

  • You are trying to hex-decode data that appears to be base64 encoded. Try using DatatypeConverter.parseBase64Binary(hex);.

  • You are creating a secret key with the algorithm "AES/CTR/NoPadding". This in invalid, just use "AES".

  • You must pass an IV/nonce value into your decryption:

    cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(...));
    

    The value you use will depend upon what CryptoJS is doing. Perhaps it uses all zeroes? Perhaps it generates a random one and you need to store it with the ciphertext?

This should be enough to get you started.

这篇关于CryptoJS AES加密和JAVA AES解密值不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆