[英]Unable to parse as integer in Android
我想對某些String
值實現encrypt
和decrypt
操作。 我已經正確加密,但是我不知道如何decrypt
該值,例如:
jsonString Values ={"Response":"NJGOkF2EvOIpfKG14LHQZrVfj\\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4\\/\\/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));
}
}
這是日志貓信息。
01-03 11:30:51.154: W/System.err(437): java.lang.NumberFormatException: unable to parse '{"' as integer
01-03 11:30:51.164: W/System.err(437): at java.lang.Integer.parse(Integer.java:383)
01-03 11:30:51.164: W/System.err(437): at java.lang.Integer.parseInt(Integer.java:372)
01-03 11:30:51.164: W/System.err(437): at java.lang.Integer.valueOf(Integer.java:528)
01-03 11:30:51.164: W/System.err(437): at com.json_to_server.SimpleCrypto.toByte(SimpleCrypto.java:63)
01-03 11:30:51.164: W/System.err(437): at com.json_to_server.SimpleCrypto.decrypt(SimpleCrypto.java:20)
01-03 11:30:51.164: W/System.err(437): at com.json_to_server.EncryptDecrypt_Demo.POST(EncryptDecrypt_Demo.java:202)
01-03 11:30:51.174: W/System.err(437): at com.json_to_server.EncryptDecrypt_Demo$HttpAsyncTask.doInBackground(EncryptDecrypt_Demo.java:267)
01-03 11:30:51.174: W/System.err(437): at com.json_to_server.EncryptDecrypt_Demo$HttpAsyncTask.doInBackground(EncryptDecrypt_Demo.java:1)
01-03 11:30:51.174: W/System.err(437): at android.os.AsyncTask$2.call(AsyncTask.java:185)
01-03 11:30:51.174: W/System.err(437): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
01-03 11:30:51.174: W/System.err(437): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
01-03 11:30:51.174: W/System.err(437): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
01-03 11:30:51.174: W/System.err(437): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
01-03 11:30:51.174: W/System.err(437): at java.lang.Thread.run(Thread.java:1019)
我想解密此值。 我不知道我必須在哪里更改SimpleCrypto class
的代碼
jsonString Values = {"Response":"NJGOkF2EvOIpfKG14LHQZrVfj\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4\/\/uxjDwtZ","statusFlag":"true"}
我假設您正在decrypting
整個JSON
字符串,並且我認為您只需要decrypt
該字符串: NJGOkF2EvOIpfKG14LHQZrVfj\\/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4\\/\\/uxjDwtZ
因此,您應該parse
JSON
並從JSON
獲取Response string
,然后將其decrypt
。
更新:您可以像這樣解析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();
}
現在,您在response variable
有了encrypted
string
。 現在您可以decrypt
response string
。
我已經測試過您的課程,並且可以正常運行。 這是我的測試:
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和AF符號。 將您的收入字符串更改為僅十六進制符號。
我認為result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
給您錯誤,因為您的十六進制字符串可能包含字符文字,因此Integer.valueOf()函數為您提供NumberFormatException
對於十六進制字符串到字節數組的轉換,請檢查[鏈接] https://stackoverflow.com/a/140861/3131537
希望能解決您的問題
您正在嘗試解析不僅包含數字而且包含文本(字符串)的整個字符串。 請檢查您的代碼,然后提出一個問題
您的解決方案有效,您對所獲取數據的解釋與實際發生的情況不一致。
您的JSON響應不是加密的字節數組,而是編碼的String 。 為了通過網絡跨字節數組(或相應的位或任何二進制數據)進行流傳輸,通常不會以原始格式發送它。 相反,您想將原始數據編碼為character 。
由於您的JSON響應看起來像字符流和字節不是原始格式,第一個假設,我可以做的是它的使用中最常見的二進制字符串編碼之一的編碼數據- Base64編碼 。
下面的字符串(響應)是有效的Base64編碼的字符串,而您的解密方法要求使用十六進制編碼的字符流。
NJGOkF2EvOIpfKG14LHQZrVfj / OEJvopi + OKU + q5G2ynDbVUnIckfMLGCCsxcY9 + BmVg + KJXF1ls \\ nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4 // uxjDwtZ
由於JSON“允許”您轉義正斜杠和其他轉義序列,因此您的Base64響應需要略微格式化。
我刪除了前斜杠的轉義符,並換行了(\\ n)的'\\'轉義符。 結果字符串看起來像(注意\\ n):
NJGOkF2EvOIpfKG14LHQZrVfj/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4//uxjDwtZ
這是有效的Base64字符串,您可以在此處進行測試(通過按回車鍵並將\\ n其余文本帶到新行中,用換行符替換\\ n)。
請注意,結果是下載了一個二進制文件-證明解碼后的值實際上是有效的二進制原始數據。
從NumberFormatException
可以明顯看出,您的decrypt
方法期望使用十六進制編碼的字符流,但它不會得到。
根據您的代碼,加密函數將返回字符串的十六進制編碼值。 這也是有效的,因為十六進制還以可讀形式表示二進制值。 但是,您可能需要在集成中進行級別設置以與編碼方案保持一致。
回到您的算法上,您的解密方法期望使用十六進制格式的加密數據,但是您得到的是Base64編碼的String。
符合您的邏輯期望(我不想更改您的原始基本代碼)
org.apache.commons.codec.binary.Base64
。 在代碼中這樣翻譯的步驟序列(在我的測試類main方法中):
String encoded = "NJGOkF2EvOIpfKG14LHQZrVfj/OEJvopi+OKU+q5G2ynDbVUnIckfMLGCCsxcY9+BmVg+KJXF1ls\\nGf2rWg73iyowyq6THyDfBS8uZnSp9PfS3bJCFb6YWX4//uxjDwtZ";
String key = "abc";
String decoded = toHex(Base64.decodeBase64(encoded));
System.out.println(decoded);
String decrypted = decrypt(key, decoded);
System.out.println(decrypted);
您的AES加密方案使用默認的AES方案( Cipher.getInstance("AES");
),它轉換為Cipher.getInstance("AES/ECB/PKCS5Padding");
在SunJCE實施中。
當我使用隨機密鑰abc
運行它時
javax.crypto.BadPaddingException: Given final block not properly padded
當然,這是密鑰錯誤的情況,因為我沒有用於加密/解密數據的密鑰。
您可以使用正確的密鑰和上述更改來測試此方案, 它應與當前的加密方案一起使用。
作為一個測試用例,我禁止解密的方法是,將解密方法中的Cipher.getInstance("AES")
替換為
Cipher.getInstance("AES/ECB/NoPadding");
我得到了一個無例外的字符集合,它們無一例外都是垃圾值,這是可以理解的-原因,我再次使用了一個與您要使用的鍵不匹配的隨機鍵。
;l:z«1†ŠåÎàÏÙQPÞ—?ñGv’€ò;PöøïÇE1:‰§ŒÔ³
您正在使用JSON數據作為字符串數據。 您只需要選擇JSON的“ response”部分值,就像這樣
JSONObject jO= new JSONObject(value);
String response = jO.getString("Response");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.