Java 无法在Android中将其解析为整数
我想对一些Java 无法在Android中将其解析为整数,java,android,encryption,aes,number-formatting,Java,Android,Encryption,Aes,Number Formatting,我想对一些字符串值执行加密和解密操作。我已正确加密,但我不知道如何解密此值,如: jsonString value={“Response:“njgokf2evoiipfkg14lhqzrvfj\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\ngf2rwg73iyowyq6hydfbs8uznsp9pfs3bjcfb6ywx4\/\/uxjDwtZ”,“statusFlag:“true”} 当我解密时,我得到了NumberFormatExc
字符串
值执行加密
和解密
操作。我已正确加密,但我不知道如何解密此值,如:
jsonString value={“Response:“njgokf2evoiipfkg14lhqzrvfj\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\ngf2rwg73iyowyq6hydfbs8uznsp9pfs3bjcfb6ywx4\/\/uxjDwtZ”,“statusFlag:“true”}
当我解密时,我得到了NumberFormatException
这是我的简单加密类
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class SimpleCrypto {
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] result = encrypt(rawKey, cleartext.getBytes());
return toHex(result);
}
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
byte[] enc = toByte(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue(); //2 * i, 2 * i + 2
return result;
}
public static String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
我想解密这个值。我不知道在我的SimpleCrypto类中我必须在哪里更改代码
jsonString Values = {"Response":"NJGOkF2EvOIpfKG14LHQZrVfj\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4\/\/uxjDwtZ","statusFlag":"true"}
我假设您正在对整个JSON
字符串进行解密,我认为您只需要解密
此字符串:
njgokf2evoipfkfkg14lhqzrvfj\/OEJvopi+OKU+q5g2yndbvunickfmlgcsxcy9+BmVg+KJXF1ls\ngf2rwg73iyowyq6hydfbs8uznsp9pfs3bjcfb6ywx4\/\/uxjDwtZ
因此,您应该解析JSON
并从JSON
获取响应字符串
,然后解密它
更新:
您可以像这样解析json字符串:
String value = "YOUR_JSON_STRING";
try {
JSONObject mJsonObject = new JSONObject(value);
String response = mJsonObject.getString("Response");
//Decrypt response string
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
现在,在响应变量
中有了加密的字符串
。现在,您可以解密响应字符串您正在尝试解析整个字符串,其中不仅包含数字,还包含文本(字符串)。请检查您的代码,然后将其作为一个问题我已经测试了您的类,并且它按照我看到的那样工作。这是我的测试:
public static void main(String[] args) throws Exception {
String message = "Some string that i want to encrypt and decrypt";
String key = "123";
String encrypted = SimpleCrypto.encrypt(key, message);
p(encrypted);
String decrypted = SimpleCrypto.decrypt(key, encrypted);
p(decrypted);
}
private static void p(String message) {
System.out.println(message);
}
和输出:
B7498FF642FA8B81289AE8E59E19F081A27B766BE3290617CC15F857BF055DA2668BF81181E26AE2F790968DF39CC070
Some string that i want to encrypt and decrypt
您将获得NumberFormatException,因为您的类仅解密已加密的字符串,但此字符串未加密 您正在尝试将整数字符串“NJ”解析为十六进制数字。但是十六进制只有0-9和A-F符号。将您的收入字符串更改为仅十六进制符号。我认为结果[I]=Integer.valueOf(hexString.substring(2*I,2*I+2),16).byteValue()
给您错误,因为您的十六进制字符串可能包含字符文字,所以整数。valueOf()函数给您提供NumberFormatException
对于十六进制字符串到字节数组的转换,请检查[链接]
希望解决您的问题您的解决方案有效,您得到的数据解释与实际发生的情况不一致
JSON响应不是加密的字节数组,而是编码的字符串。要通过网络在字节数组(或比特或任何二进制数据)中传输数据,通常不会以原始格式发送。相反,您希望将原始数据编码为字符
由于JSON响应看起来像一个字符流,而不是一个原始的字节格式,因此我可以做的第一个假设是,它是一个使用最常见的二进制到字符串编码之一的编码数据-Base64
下面的字符串(响应)是有效的Base64编码字符串,而解密方法需要十六进制编码的字符流
NJGOKF2VOIPFKG14LHQZRVFJ/OEJvopi+OKU+Q5G2YNDVUNICKFMLGCCSxCY9+BmVg+KJXF1ls\NGF2RWG73IOWYQ6HYDFBS8UZNSP9PFS3BJCFB6YWX4//uxjDwtZ
提取正确的响应:
由于JSON“允许”您转义前斜杠和其他转义序列,因此Base64响应需要稍微格式化
我删除了前斜杠的转义符,删除了换行符(\n)的“\”转义符。结果字符串如下所示(注意\n):
这是一个有效的Base64字符串,您可以对其进行测试(按enter键并将其余文本移到新行,以换行符替换)
请注意,它下载了一个二进制文件,这证明了解码值实际上是一个有效的二进制原始数据
修复代码:
从NumberFormatException
中可以明显看出,您的decrypt
方法需要一个十六进制编码的字符流,但它没有得到
根据您的代码,encrypt函数将返回字符串的十六进制编码值。这也是有效的,因为十六进制也是二进制值的可读形式表示。但是,您可能需要在集成中设置级别以与编码方案保持一致
回到您的算法,您的解密方法期望加密数据以Hex形式出现,但您得到的是Base64编码字符串
与您的逻辑预期一致(我不想更改您的原始基本代码)
我们必须解码Base64编码字符串-各种风格都可用,我在本测试中使用了org.apache.commons.codec.binary.Base64
将其转换为十六进制
将其馈送到解密方法
在代码中(在我的测试类main方法中)这样翻译的步骤序列:
关于加密方案的要点:
AES加密方案使用默认的AES方案(Cipher.getInstance(“AES”);
),该方案转换为Cipher.getInstance(“AES/ECB/PKCS5Padding”)
当我使用随机键abc
javax.crypto.BadPaddingException: Given final block not properly padded
这当然是一个错误密钥的场景,因为我没有用于加密/解密数据的密钥
您可以使用正确的密钥和上面提到的更改来测试此方案,它应该与您当前的加密方案一起工作。
我的测试用例:
作为一个测试用例,我将decrypt方法中的Cipher.getInstance(“AES”)
替换为
Cipher.getInstance("AES/ECB/NoPadding");
我得到了一组不可读的字符,它们都是垃圾值,这是可以理解的,因为我再次使用了一个随机键,它与您想要使用的不一致
;l:z«1†ŠåÎàÏÙQPÞ—?ñGv’€ò;PöøïÇE1:‰§ŒÔ³
javax.crypto.BadPaddingException: Given final block not properly padded
Cipher.getInstance("AES/ECB/NoPadding");
;l:z«1†ŠåÎàÏÙQPÞ—?ñGv’€ò;PöøïÇE1:‰§ŒÔ³
JSONObject jO= new JSONObject(value);
String response = jO.getString("Response");