久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

如何解密在 Laravel 中使用 Crypt 加密的 Java (Andro

How to decrypt in Java (Android) text that was encrypted with Crypt in Laravel?(如何解密在 Laravel 中使用 Crypt 加密的 Java (Android) 文本?)
本文介紹了如何解密在 Laravel 中使用 Crypt 加密的 Java (Android) 文本?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我需要解密我從服務器接收到的一些數(shù)據(jù),制作 API 的程序員將我引導到這個 Encrypter 類,看看他用來加密什么.

現(xiàn)在基于該類,我發(fā)現(xiàn)使用的算法是 AES128 CBC,并且我收到的字符串是 Base64 編碼的,并且包含其他數(shù)據(jù),而不僅僅是密文.

即如果我收到以下字符串:

<預> <代碼> eyJpdiI6InJsSzRlU3pDZTBBUVNwMzdXMjVcL0tBPT0iLCJ2YWx1ZSI6Ik5JOENsSVVWaWk2RGNhNlwvWjJNeG94UzVkclwvMGJOREQreWUyS1UzclRMND0iLCJtYWMiOiJhZTZkYjNkNGM2ZTliNmU0ZTc0MTRiNDBmMzFlZTJhNTczZWIxMjk4N2YwMjlhODA1NTIyMDEzODljNDY2OTk2In0

base64 解碼后我得到:

{iv":rlK4eSzCe0AQSp37W25/KA==",值":NI8ClIUVii6Dca6/Z2MxoxS5dr/0bNDD+ye2KU3rTL4=",mac":"ae6db3d4c6e9b6e4e7414b40f31ee2a573eb12987f029a80552201389c466996"}

基于 Encrypter 類的 line 99 ( iv = base64_decode($payload['iv']); ),我執(zhí)行了另一個在 ivvalue 上進行 base64 解碼,得到長度為 16 的 iv.我將這些作為參數(shù)傳遞給下面的函數(shù):

 public static String decrypt(String iv, String encryptedData) 拋出異常 {byte[] keyValue = "zy2dEd1pKG5i3WuWbvOBolFQR84AYbvN".getBytes();Key key = new SecretKeySpec(keyValue, "AES");Cipher c = Cipher.getInstance(AES/CBC/PKCS7Padding");c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes()));byte[] decordedValue = Base64.decode(encryptedData.getBytes(), Base64.DEFAULT);字節(jié)[] decValue = c.doFinal(decordedValue);返回新字符串(decValue);}

但我收到以下錯誤:

10-06 19:13:33.601 12895-12895/?W/System.err:java.security.InvalidAlgorithmParameterException:預期的 IV 長度為 1610-06 19:13:33.601 12895-12895/?W/System.err:在 com.android.org.conscrypt.OpenSSLCipher.engineInitInternal(OpenSSLCipher.java:281)10-06 19:13:33.601 12895-12895/?W/System.err:在 com.android.org.conscrypt.OpenSSLCipher.engineInit(OpenSSLCipher.java:323)10-06 19:13:33.601 12895-12895/?W/System.err:在 javax.crypto.Cipher.init(Cipher.java:751)10-06 19:13:33.601 12895-12895/?W/System.err:在 javax.crypto.Cipher.init(Cipher.java:701)10-06 19:13:33.601 12895-12895/?W/System.err:在 com.example.kushtrim.testproject.MainActivity.decrypt(MainActivity.java:62)10-06 19:13:33.601 12895-12895/?W/System.err:在 com.example.kushtrim.testproject.MainActivity.onCreate(MainActivity.java:45)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.Activity.performCreate(Activity.java:5990)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.ActivityThread.access$800(ActivityThread.java:151)10-06 19:13:33.601 12895-12895/?W/System.err:在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)10-06 19:13:33.602 12895-12895/?W/System.err:在 android.os.Handler.dispatchMessage(Handler.java:102)10-06 19:13:33.602 12895-12895/?W/System.err:在 android.os.Looper.loop(Looper.java:135)10-06 19:13:33.602 12895-12895/?W/System.err:在 android.app.ActivityThread.main(ActivityThread.java:5254)10-06 19:13:33.602 12895-12895/?W/System.err:在 java.lang.reflect.Method.invoke(Native Method)10-06 19:13:33.602 12895-12895/?W/System.err:在 java.lang.reflect.Method.invoke(Method.java:372)10-06 19:13:33.602 12895-12895/?W/System.err:在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)10-06 19:13:33.602 12895-12895/?W/System.err:在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

注意:字符串 iv 的長度為 16,但 iv.getBytes() 返回一個長度為 26 的數(shù)組.

誰能指出我哪里出錯了,我該如何解決.謝謝/

編輯
評論后,我做了一些更改,解決了上述錯誤:
在我對 iv 進行 base64 解碼之前,將字節(jié)轉換為字符串,然后將該字符串傳遞給解密方法,該方法反過來調用它的 getBytes().不知何故,這使得字節(jié)數(shù)組的長度為 26.
將我base64解碼后得到的字節(jié)數(shù)組發(fā)送到decrypt方法解決了問題.
現(xiàn)在方法如下:

public static String decrypt(byte[] iv, String encryptedData) 拋出異常 {byte[] keyValue = "zy2dEd1pKG5i3WuWbvOBolFQR84AYbvN".getBytes();Key key = new SecretKeySpec(keyValue, "AES");Cipher c = Cipher.getInstance(AES/CBC/PKCS7Padding");c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));byte[] decordedValue = Base64.decode(encryptedData.getBytes(), Base64.DEFAULT);字節(jié)[] decValue = c.doFinal(decordedValue);返回新字符串(decValue);}

現(xiàn)在我又遇到了一個奇怪的問題:
我首先加密的文本是 KushtrimPacaj ,但解密后的文本是 s:13:"KushtrimPacaj"; .那另一部分是從哪里來的?13或許代表KushtrimPacaj的長度?

編輯
這是工作代碼,以防萬一有人需要它:
https://gist.github.com/KushtrimPacaj/43a383ab419fc222f80e

解決方案

可以在padAndMcrypt() 函數(shù),即給定的 $value 使用 PHP 的 serialize() 函數(shù).你可以重新實現(xiàn) unserialize() 函數(shù),或者如果您總是在 PHP 中加密字符串,您可以自己拆分字節(jié)數(shù)組.

int firstQuoteIndex = 0;while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));

完整代碼:

public static String decrypt(byte[] keyValue, String ivValue, String encryptedData) 拋出異常 {Key key = new SecretKeySpec(keyValue, "AES");byte[] iv = Base64.decode(ivValue.getBytes("UTF-8"), Base64.DEFAULT);byte[] decodedValue = Base64.decode(encryptedData.getBytes("UTF-8"), Base64.DEFAULT);密碼 c = Cipher.getInstance("AES/CBC/PKCS7Padding");//或 PKCS5Paddingc.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));byte[] decValue = c.doFinal(decodedValue);int firstQuoteIndex = 0;while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));}

驗證 MAC 始終是一個好主意,因為它可以防止一些攻擊,例如填充預言攻擊.這也是一種很好的檢測密文一般修改的方法.

帶有 MAC 驗證的完整代碼:

public static String decrypt(byte[] keyValue, String ivValue, String encryptedData, String macValue) 拋出異常 {Key key = new SecretKeySpec(keyValue, "AES");byte[] iv = Base64.decode(ivValue.getBytes("UTF-8"), Base64.DEFAULT);byte[] decodedValue = Base64.decode(encryptedData.getBytes("UTF-8"), Base64.DEFAULT);SecretKeySpec macKey = new SecretKeySpec(keyValue, "HmacSHA256");Mac hmacSha256 = Mac.getInstance("HmacSHA256");hmacSha256.init(macKey);hmacSha256.update(ivValue.getBytes("UTF-8"));byte[] calcMac = hmacSha256.doFinal(encryptedData.getBytes("UTF-8"));byte[] mac = Hex.decodeHex(macValue.toCharArray());if (!secureEquals(calcMac, mac))返回空值;//或拋出異常密碼 c = Cipher.getInstance("AES/CBC/PKCS7Padding");//或 PKCS5Paddingc.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));byte[] decValue = c.doFinal(decodedValue);int firstQuoteIndex = 0;while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));}/* 恒定時間比較以防止對無效身份驗證標簽的定時攻擊.*/公共靜態(tài)布爾secureEquals(最終字節(jié)[]已知,最終字節(jié)[]用戶){int knownLen = known.length;int userLen = user.length;int 結果 = knownLen ^ userLen;for (int i = 0; i < knownLen; i++) {結果 |= 已知[i] ^ 用戶[i % userLen];}返回結果 == 0;}

I need to decrypt some data that I receive from the server, and the programmer who made the API directed me to this Encrypter class, to see what he used to encrypt.

Now based on that class, I found that the algorithm used is AES128 CBC, and that the string I receive is Base64 encoded and contains other data, not just the ciphertext.

Namely that if I receive the following String:

eyJpdiI6InJsSzRlU3pDZTBBUVNwMzdXMjVcL0tBPT0iLCJ2YWx1ZSI6Ik5JOENsSVVWaWk2RGNhNlwvWjJNeG94UzVkclwvMGJOREQreWUyS1UzclRMND0iLCJtYWMiOiJhZTZkYjNkNGM2ZTliNmU0ZTc0MTRiNDBmMzFlZTJhNTczZWIxMjk4N2YwMjlhODA1NTIyMDEzODljNDY2OTk2In0

after base64 decoding I get:

{"iv":"rlK4eSzCe0AQSp37W25/KA==","value":"NI8ClIUVii6Dca6/Z2MxoxS5dr/0bNDD+ye2KU3rTL4=","mac":"ae6db3d4c6e9b6e4e7414b40f31ee2a573eb12987f029a80552201389c466996"}

Based on line 99 of Encrypter class ( iv = base64_decode($payload['iv']); ), I performed another base64 decode on the iv and the value , and got an iv of length 16. Those I passed as parameters to the function below:

    public static String decrypt(String iv, String encryptedData) throws Exception {
    byte[] keyValue = "zy2dEd1pKG5i3WuWbvOBolFQR84AYbvN".getBytes();
    Key key = new SecretKeySpec(keyValue, "AES");        
    Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding");
    c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv.getBytes()));
    byte[] decordedValue = Base64.decode(encryptedData.getBytes(), Base64.DEFAULT);
    byte[] decValue = c.doFinal(decordedValue);
    return new String(decValue);
}

But I'm getting the following error:

10-06 19:13:33.601 12895-12895/? W/System.err: java.security.InvalidAlgorithmParameterException: expected IV length of 16
10-06 19:13:33.601 12895-12895/? W/System.err:     at com.android.org.conscrypt.OpenSSLCipher.engineInitInternal(OpenSSLCipher.java:281)
10-06 19:13:33.601 12895-12895/? W/System.err:     at com.android.org.conscrypt.OpenSSLCipher.engineInit(OpenSSLCipher.java:323)
10-06 19:13:33.601 12895-12895/? W/System.err:     at javax.crypto.Cipher.init(Cipher.java:751)
10-06 19:13:33.601 12895-12895/? W/System.err:     at javax.crypto.Cipher.init(Cipher.java:701)
10-06 19:13:33.601 12895-12895/? W/System.err:     at com.example.kushtrim.testproject.MainActivity.decrypt(MainActivity.java:62)
10-06 19:13:33.601 12895-12895/? W/System.err:     at com.example.kushtrim.testproject.MainActivity.onCreate(MainActivity.java:45)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.Activity.performCreate(Activity.java:5990)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.ActivityThread.access$800(ActivityThread.java:151)
10-06 19:13:33.601 12895-12895/? W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
10-06 19:13:33.602 12895-12895/? W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:102)
10-06 19:13:33.602 12895-12895/? W/System.err:     at android.os.Looper.loop(Looper.java:135)
10-06 19:13:33.602 12895-12895/? W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5254)
10-06 19:13:33.602 12895-12895/? W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
10-06 19:13:33.602 12895-12895/? W/System.err:     at java.lang.reflect.Method.invoke(Method.java:372)
10-06 19:13:33.602 12895-12895/? W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
10-06 19:13:33.602 12895-12895/? W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Note: The String iv has length of 16, but iv.getBytes() returns an array of length 26.

Could someone point me to where I went wrong, and how do I fix it. Thanks/

EDIT
After the comment, I made some changes, that resolved the above error:
Before I was base64 decoding iv, converting the bytes to String, then passing that String to the decrypt method, which in return called the getBytes() on it. Somehow this made the byte array have a length of 26.
Sending the byte array I obtained after base64 decoding to the decrypt method fixed the problem.
Now the method is as follows:

public static String decrypt(byte[] iv, String encryptedData) throws Exception {
    byte[] keyValue = "zy2dEd1pKG5i3WuWbvOBolFQR84AYbvN".getBytes();
    Key key = new SecretKeySpec(keyValue, "AES");
    Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding");
    c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    byte[] decordedValue = Base64.decode(encryptedData.getBytes(), Base64.DEFAULT);
    byte[] decValue = c.doFinal(decordedValue);
    return new String(decValue);
}

Now I have another weird problem:
The text I encrypted on the first place was KushtrimPacaj , but the decrypted text is s:13:"KushtrimPacaj"; . Where is that other part coming from ? 13 perhaps represents the length of KushtrimPacaj ?

Edit
Here's the working code, in case anyone needs it :
https://gist.github.com/KushtrimPacaj/43a383ab419fc222f80e

解決方案

You can see in the padAndMcrypt() function, that the given $value is serialized using PHP's serialize() function. You can re-implement the unserialize() function in Java or you can split the byte array yourself if you're always encrypting strings in PHP.

int firstQuoteIndex = 0;
while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;
return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));

Full code:

public static String decrypt(byte[] keyValue, String ivValue, String encryptedData) throws Exception {
    Key key = new SecretKeySpec(keyValue, "AES");
    byte[] iv = Base64.decode(ivValue.getBytes("UTF-8"), Base64.DEFAULT);
    byte[] decodedValue = Base64.decode(encryptedData.getBytes("UTF-8"), Base64.DEFAULT);

    Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding"); // or PKCS5Padding
    c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    byte[] decValue = c.doFinal(decodedValue);

    int firstQuoteIndex = 0;
    while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;
    return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));
}

Verifying the MAC is always a good idea, because it prevents some attacks such as the padding oracle attack. It is also a very good way to detect general modifications of ciphertexts.

Full code with MAC verification:

public static String decrypt(byte[] keyValue, String ivValue, String encryptedData, String macValue) throws Exception {
    Key key = new SecretKeySpec(keyValue, "AES");
    byte[] iv = Base64.decode(ivValue.getBytes("UTF-8"), Base64.DEFAULT);
    byte[] decodedValue = Base64.decode(encryptedData.getBytes("UTF-8"), Base64.DEFAULT);

    SecretKeySpec macKey = new SecretKeySpec(keyValue, "HmacSHA256");
    Mac hmacSha256 = Mac.getInstance("HmacSHA256");
    hmacSha256.init(macKey);
    hmacSha256.update(ivValue.getBytes("UTF-8"));
    byte[] calcMac = hmacSha256.doFinal(encryptedData.getBytes("UTF-8"));
    byte[] mac = Hex.decodeHex(macValue.toCharArray());
    if (!secureEquals(calcMac, mac))
        return null; // or throw exception

    Cipher c = Cipher.getInstance("AES/CBC/PKCS7Padding"); // or PKCS5Padding
    c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
    byte[] decValue = c.doFinal(decodedValue);

    int firstQuoteIndex = 0;
    while(decValue[firstQuoteIndex] != (byte)'"') firstQuoteIndex++;
    return new String(Arrays.copyOfRange(decValue, firstQuoteIndex + 1, decValue.length-2));
}

/* Constant-time compare to prevent timing attacks on invalid authentication tags. */
public static boolean secureEquals(final byte[] known, final byte[] user) {
    int knownLen = known.length;
    int userLen = user.length;

    int result = knownLen ^ userLen;
    for (int i = 0; i < knownLen; i++) {
        result |= known[i] ^ user[i % userLen];
    }
    return result == 0;
}

這篇關于如何解密在 Laravel 中使用 Crypt 加密的 Java (Android) 文本?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權益,請聯(lián)系我們刪除處理,感謝您的支持!

相關文檔推薦

Java Remove Duplicates from an Array?(Java從數(shù)組中刪除重復項?)
How to fix Invocation failed Unexpected Response from Server: Unauthorized in Android studio(如何修復調用失敗來自服務器的意外響應:在 Android 工作室中未經(jīng)授權)
AES encryption, got extra trash characters in decrypted file(AES 加密,解密文件中有多余的垃圾字符)
AES Error: Given final block not properly padded(AES 錯誤:給定的最終塊未正確填充)
Detecting incorrect key using AES/GCM in JAVA(在 JAVA 中使用 AES/GCM 檢測不正確的密鑰)
AES-256-CBC in Java(Java 中的 AES-256-CBC)
主站蜘蛛池模板: a级黄色片 | 中文字幕不卡视频 | 精品国产一区二区三区久久久蜜月 | 欧美资源在线 | 国产黄色一区二区 | 久久精品一区二区三区不卡牛牛 | 国产青青操 | 亚洲精品中文字幕乱码三区91 | 亚洲免费婷婷 | 中文字幕理伦片免费看 | 国产黄在线 | 国产精品久久久久久久久久久久久久 | hdxxxxhd100%| 欧美超碰在线 | 国产欧美在线观看 | 日韩黄色小视频 | 高hnp失禁3p小公主 | 国产一区二区三区久久 | 啪啪免费网站 | 国产伦精品一区二区三区免费 | 色妞网 | 国产美女精品 | 九九成人| 欧美日韩国产中文 | 97caoporn| 成人做受黄大片 | 国内精品一区二区 | 黄色录像大片 | 狠狠干免费视频 | 日韩精品福利 | 久久超 | 天天草天天干 | 成人在线不卡 | 久久96| 激情综合五月天 | 91靠逼视频| 男女瑟瑟视频 | 精品国产91乱码一区二区三区 | 日韩成人小视频 | 五月婷婷网站 | 国产丝袜视频 |