如何在javascript中获得encryptJs的java等价物
我已经在cryptoJs上工作了一周了,但我面临的问题是Javascript。我是Javascript的新手,我真的需要你的帮助 我有以下基于cryptojs的java加密/解密代码,这些代码工作得非常好,但我正在尝试使用Javascript等效代码 我得到了不同的加密 在java中我得到了:如何在javascript中获得encryptJs的java等价物,javascript,java,encryption,Javascript,Java,Encryption,我已经在cryptoJs上工作了一周了,但我面临的问题是Javascript。我是Javascript的新手,我真的需要你的帮助 我有以下基于cryptojs的java加密/解密代码,这些代码工作得非常好,但我正在尝试使用Javascript等效代码 我得到了不同的加密 在java中我得到了:2BECE44E5375C690FE5785CA9C4814868D620F600AFFA14584B2B7E336742AEF9D52D4102962AD81E9A1267ED48A466B2B739E7
2BECE44E5375C690FE5785CA9C4814868D620F600AFFA14584B2B7E336742AEF9D52D4102962AD81E9A1267ED48A466B2B739E71FB34CE9F4ED7661BFA3504C7BA70583E2BC315A1EE89167F06309D6B3D1CF69DC1028F1396E5815048BF
在使用javascript时,我得到了:2A478540C889DA6BED186C21C7133D1
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.security.sasl.SaslException;
import javax.security.*;
public class AESCrypter {
private String iv = "9%Ysr^xyBTrPr!$Y";
private String secretkey = "GnxUFjKw9(bk7Ay$";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public static void main(String args[]) throws UnsupportedEncodingException, Exception {
AESCrypter crypta = new AESCrypter();
//String toenc = "1";
String toenc = " “srcAccount”:\"0011295527\",\r\n" +
"“requestId\":\"12345678901234567890\",\r\n" +
"“pin”:\"3019\"";
String enc = "";
String dec = "";
// encrypt the value
//enc = crypta.encrypt(toenc);
enc = crypta.encrypt(toenc);
// encrypted value print out
System.out.println(" ENCED : " + enc);
// decrypt the value
dec = crypta.decrypt(enc);
// decrypted value print out
System.out.println(" DECED : " + dec);
}
public AESCrypter(String keyz, String ivStr) {
ivspec = new IvParameterSpec(ivStr.getBytes());
keyspec = new SecretKeySpec(keyz.getBytes(), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public AESCrypter()
{
ivspec = new IvParameterSpec(iv.getBytes());
keyspec = new SecretKeySpec(secretkey.getBytes(), "AES");
System.out.println("this ivspec = " + ivspec);
try
{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}}
public String encrypt(String text) throws SecurityException {
System.out.println("text = " + text);
if (text == null || text.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
} catch (Exception e) {
throw new SecurityException("[encrypt] " + e.getMessage());
}
return bytesToHex(encrypted);
}
public String decrypt(String code) throws SecurityException, UnsupportedEncodingException {
if (code == null || code.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException("[decrypt] " + e.getMessage());
}
return new String(decrypted, "UTF-8");
}
public static String bytesToHex(byte[] data)
{
if (data==null) {
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF)<16) {
str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
}
else {
str = str + java.lang.Integer.toHexString(data[i]&0xFF);
}}return str;
}
public static byte[] hexToBytes(String str) {
if (str == null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
}
return buffer;
}
}
}
有人能给我指一下正确的方向吗。由于您在Java和Javascript中使用了不同的键和iv值,很可能会得到不同的结果 在Java和Javascript中,正如@Artjom B告诉您的那样 此外,您的“要加密的消息”(“toenc”或“正文”)也不同,不会得到相同的结果 我设置了一个简化的Java程序,并调整了一些缺少的字符集编码。为了简单起见,我只使用了一个简单的字符串来测试en-并在两侧进行解密-我让您为Java和Javascript上的“要加密的消息”找到一个相同的解决方案 Javascript程序使用CryptoJS进行加密,并为key、iv和明文获取相同的输入值 两个程序以十六进制给出相同的加密值:
525106e181b2ad0b507439f54d690dfaa6e22ae2c96cde79c532a2b868d5e824637b91cc59854592343c26c39f83f452
请注意:这两个程序都没有任何异常处理,仅用于教育目的。
对于现场测试,我设置了两个“小提琴”,您可以使用自己的值测试程序:
爪哇:
Javascript:
Java代码:
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
public class Main {
private String iv = "9%Ysr^xyBTrPr!$Y";
private String secretkey = "GnxUFjKw9(bk7Ay$";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public static void main(String args[]) throws UnsupportedEncodingException, Exception {
Main crypta = new Main();
//String toenc = "1";
/*
String toenc = " “srcAccount”:\"0011295527\",\r\n" +
"“requestId\":\"12345678901234567890\",\r\n" +
"“pin”:\"3019\"";
*/
String toenc = "The quick brown fox jumps over the lazy dog";
String enc = "";
String dec = "";
// encrypt the value
//enc = crypta.encrypt(toenc);
enc = crypta.encrypt(toenc);
// encrypted value print out
System.out.println(" ENCED : " + enc);
// decrypt the value
dec = crypta.decrypt(enc);
// decrypted value print out
System.out.println(" DECED : " + dec);
}
public Main(String keyz, String ivStr) {
ivspec = new IvParameterSpec(ivStr.getBytes(StandardCharsets.UTF_8));
keyspec = new SecretKeySpec(keyz.getBytes(StandardCharsets.UTF_8), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public Main()
{
ivspec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
keyspec = new SecretKeySpec(secretkey.getBytes(StandardCharsets.UTF_8), "AES");
System.out.println("this ivspec = " + ivspec);
try
{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}}
public String encrypt(String text) throws SecurityException {
System.out.println("text = " + text);
if (text == null || text.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
throw new SecurityException("[encrypt] " + e.getMessage());
}
return bytesToHex(encrypted);
}
public String decrypt(String code) throws SecurityException, UnsupportedEncodingException {
if (code == null || code.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException("[decrypt] " + e.getMessage());
}
return new String(decrypted, StandardCharsets.UTF_8);
}
public static String bytesToHex(byte[] data)
{
if (data==null) {
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF)<16) {
str = str + "0" + Integer.toHexString(data[i]&0xFF);
}
else {
str = str + Integer.toHexString(data[i]&0xFF);
}}return str;
}
public static byte[] hexToBytes(String str) {
if (str == null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
}
return buffer;
}
}
}
当您在Java和Javascript中使用不同的键和iv值时,很可能会得到不同的结果 在Java和Javascript中,正如@Artjom B告诉您的那样 此外,您的“要加密的消息”(“toenc”或“正文”)也不同,不会得到相同的结果 我设置了一个简化的Java程序,并调整了一些缺少的字符集编码。为了简单起见,我只使用了一个简单的字符串来测试en-并在两侧进行解密-我让您为Java和Javascript上的“要加密的消息”找到一个相同的解决方案 Javascript程序使用CryptoJS进行加密,并为key、iv和明文获取相同的输入值 两个程序以十六进制给出相同的加密值:
525106e181b2ad0b507439f54d690dfaa6e22ae2c96cde79c532a2b868d5e824637b91cc59854592343c26c39f83f452
请注意:这两个程序都没有任何异常处理,仅用于教育目的。
对于现场测试,我设置了两个“小提琴”,您可以使用自己的值测试程序:
爪哇:
Javascript:
Java代码:
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
public class Main {
private String iv = "9%Ysr^xyBTrPr!$Y";
private String secretkey = "GnxUFjKw9(bk7Ay$";
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public static void main(String args[]) throws UnsupportedEncodingException, Exception {
Main crypta = new Main();
//String toenc = "1";
/*
String toenc = " “srcAccount”:\"0011295527\",\r\n" +
"“requestId\":\"12345678901234567890\",\r\n" +
"“pin”:\"3019\"";
*/
String toenc = "The quick brown fox jumps over the lazy dog";
String enc = "";
String dec = "";
// encrypt the value
//enc = crypta.encrypt(toenc);
enc = crypta.encrypt(toenc);
// encrypted value print out
System.out.println(" ENCED : " + enc);
// decrypt the value
dec = crypta.decrypt(enc);
// decrypted value print out
System.out.println(" DECED : " + dec);
}
public Main(String keyz, String ivStr) {
ivspec = new IvParameterSpec(ivStr.getBytes(StandardCharsets.UTF_8));
keyspec = new SecretKeySpec(keyz.getBytes(StandardCharsets.UTF_8), "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public Main()
{
ivspec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
keyspec = new SecretKeySpec(secretkey.getBytes(StandardCharsets.UTF_8), "AES");
System.out.println("this ivspec = " + ivspec);
try
{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
catch (NoSuchPaddingException e)
{
e.printStackTrace();
}}
public String encrypt(String text) throws SecurityException {
System.out.println("text = " + text);
if (text == null || text.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
throw new SecurityException("[encrypt] " + e.getMessage());
}
return bytesToHex(encrypted);
}
public String decrypt(String code) throws SecurityException, UnsupportedEncodingException {
if (code == null || code.length() == 0) {
throw new SecurityException("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException("[decrypt] " + e.getMessage());
}
return new String(decrypted, StandardCharsets.UTF_8);
}
public static String bytesToHex(byte[] data)
{
if (data==null) {
return null;
}
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF)<16) {
str = str + "0" + Integer.toHexString(data[i]&0xFF);
}
else {
str = str + Integer.toHexString(data[i]&0xFF);
}}return str;
}
public static byte[] hexToBytes(String str) {
if (str == null) {
return null;
} else if (str.length() < 2) {
return null;
} else {
int len = str.length() / 2;
byte[] buffer = new byte[len];
for (int i = 0; i < len; i++) {
buffer[i] = (byte) Integer.parseInt(str.substring(i * 2, i * 2 + 2), 16);
}
return buffer;
}
}
}
看来你走对了方向。上面的代码是否加密了您的数据?少了什么?它在做什么,不应该做什么?如果您将console.log(加密);在最后一行之后的那一行上,函数工作了吗?为什么
CryptoJS.pad.NoPadding
?这是错误的,因为您使用的是PKCS#5(=PKCS#7)填充。同时使用相同的IV和密钥。IV不一定是秘密的。对于CBC模式,它需要不可预测。在加密过程中,我们通常在密文前面写,在解密之前将其切掉。@ArtjomB。您能帮我看一下代码示例吗?我也更新了我的问题。谢谢。@ArtjomB。我确实用了同样的静脉注射,看起来你走对了方向。上面的代码是否加密了您的数据?少了什么?它在做什么,不应该做什么?如果您将console.log(加密);在最后一行之后的那一行上,函数工作了吗?为什么CryptoJS.pad.NoPadding
?这是错误的,因为您使用的是PKCS#5(=PKCS#7)填充。同时使用相同的IV和密钥。IV不一定是秘密的。对于CBC模式,它需要不可预测。在加密过程中,我们通常在密文前面写,在解密之前将其切掉。@ArtjomB。您能帮我看一下代码示例吗?我也更新了我的问题。谢谢。@ArtjomB。我确实用了同样的静脉注射。