成功获取正确的加密值但面临解密该值的问题(已加密)。
值:123456
已加密:ncSzDj4j8l44iM5qgaqHgA ==
为什么我得到了java.lang.Exception:[decrypt]无效的int:" Bo" ?
是否有任何解决方案/建议,我们将不胜感激。谢谢
MainActivity.java
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.net.URLDecoder;
public class MainActivity extends AppCompatActivity {
ApiCrypter3 apiCrypter;
//123456
//ncSzDj4j8l44iM5qgaqHgA==
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiCrypter = new ApiCrypter3();
try {
byte[] encryptedRequest = this.apiCrypter.encrypt(value);
String EncryptStr = new String(encryptedRequest, "UTF-8");
Log.e("ENCRYPTION: ", EncryptStr.toString());
String res = new String(this.apiCrypter.decrypt(EncryptStr), "UTF-8");
res = URLDecoder.decode(res, "UTF-8");
Log.e("DECRYPTION: ", res.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
ApiCrypter3.java
package <your package name>;
import android.util.Base64;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class ApiCrypter3 {
private byte[] sessionKey = {your 16 character key}; //Where you get this from is beyond the scope of this post
private byte[] iv = {your 16 character value}; //Ditto
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public ApiCrypter3()
{
ivspec = new IvParameterSpec(iv);
keyspec = new SecretKeySpec(sessionKey, "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public byte[] encrypt(String text) throws Exception
{
if(text == null || text.length() == 0) {
throw new Exception("Empty string");
}
byte[] encrypted = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = Base64.encode(cipher.doFinal(text.getBytes("UTF-8")), Base64.DEFAULT);
}
catch (Exception e) {
throw new Exception("[encrypt] " + e.getMessage());
}
return encrypted;
}
public byte[] decrypt(String code) throws Exception
{
if(code == null || code.length() == 0) {
throw new Exception("Empty string");
}
byte[] decrypted = null;
try {
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
//decrypted = Base64.decode(cipher.doFinal(code.getBytes()),Base64.DEFAULT);
decrypted = Base64.decode(cipher.doFinal(hexToBytes(code)),Base64.DEFAULT);
}
catch (Exception e) {
throw new Exception("[decrypt] " + e.getMessage());
}
return decrypted;
}
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++) {
//No effect
//buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
buffer[i]=Integer.valueOf(str.substring(i*2,i*2+2),16).byteValue();
}
return buffer;
}
}
}
日志:
04-29 16:51:26.399 10918-10918/com.test.com.encrytiondecryption E/ENCRYPTION:: ncSzDj4j8l44iM5qgaqHgA==
04-29 16:51:26.399 10918-10918/com.test.com.encrytiondecryption W/System.err: java.lang.Exception: [decrypt] Invalid int: "nc"
04-29 16:51:26.399 10918-10918/com.test.com.encrytiondecryption W/System.err: at com.test.com.encrytiondecryption.ApiCrypter3.decrypt(ApiCrypter3.java:64)
04-29 16:51:26.399 10918-10918/com.test.com.encrytiondecryption W/System.err: at com.test.com.encrytiondecryption.MainActivity.onCreate(MainActivity.java:41)
答案 0 :(得分:2)
这样简单的方法::
package com.encrytiondecryption;
import android.util.Base64;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class ApiCrypter5 {
byte[] sessionKey = {your 16 character key}; //Where you get this from is beyond the scope of this post
private byte[] iv = {your 16 character value }; //Ditto
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
public ApiCrypter5() {
ivspec = new IvParameterSpec(iv);
keyspec = new SecretKeySpec(sessionKey, "AES");
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public String encrytData(String text) throws Exception {
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] results = cipher.doFinal(text.getBytes());
return Base64.encodeToString(results, Base64.NO_WRAP | Base64.DEFAULT);
}
public String decryptData(String text) throws Exception {
byte[] encryted_bytes = Base64.decode(text, Base64.DEFAULT);
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] decrypted = cipher.doFinal(encryted_bytes);
return new String(decrypted);
}
}
答案 1 :(得分:1)
您的hexToBytes
函数中的这一行似乎抛出异常,然后在decrypt
中捕获并重新抛出:
buffer[i]=Integer.valueOf(str.substring(i*2,i*2+2),16).byteValue();
问题是您传递给hexToBytes函数的字符串是Base64编码的,它不是十六进制字符串,因此将前两个字符作为整数读取会导致异常。
将解密中的行更改为:
decrypted = cipher.doFinal(Base64.decode(code,Base64.DEFAULT));
当您加密时,您正在加密,然后是Base64编码,因此当您解密时,您应该按相反的顺序执行:Base64解码然后解密。