所以我在從基於字符串的密碼生成密鑰時遇到了問題。加密步驟正常工作,解密步驟將運行直到底部列出的錯誤,並使解密的文件損壞。我用下面的函數來執行加密/解密:EVP_DecryptFinal_ex:糟糕的解密,Android中可能的密鑰生成問題
public static boolean decryptFileFromUri(Context context, Uri file, String keyphrase) {
try {
File f = new File(getRealPathFromURI(context, file));
FileInputStream fis = new FileInputStream(f);
File ef = new File(f.toString().replace(".epf", ""));
FileOutputStream fos = new FileOutputStream(ef);
Log.d("HIDEMYPICS","Decrypting: " + f.toString());
byte[] rawKey = getRawKey(keyphrase.getBytes("UTF8"));
/*KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(rawKey);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();*/
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
Log.d("HIDEMYPICS","Decrypted to: " + ef.toString());
return true;
} catch (IOException e){
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return false;
}
public static boolean encryptFileFromUri(Context context, Uri file, String keyphrase) {
try {
File f = new File(getRealPathFromURI(context, file));
FileInputStream fis = new FileInputStream(f);
File ef = new File(f.toString() + ".epf");
FileOutputStream fos = new FileOutputStream(ef);
Log.d("HIDEMYPICS","Encrypting: " + f.toString());
byte[] rawKey = getRawKey(keyphrase.getBytes("UTF8"));
/*KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(rawKey);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();*/
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
Log.d("HIDEMYPICS","Encrypted to: " + ef.toString());
return true;
} catch (IOException e){
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return false;
}
而這裏的生成原始密鑰的功能:
private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException {
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();
String result = "";
for(int index = 0; index < raw.length; index++) {
result += Integer.toHexString(raw[index]);
// maybe you have to convert your byte to int before this can be done
// (cannot check reight now)
}
Log.d("HIDEMYPICS","Passphrase: " + new String(seed).toString() + " Key: " + result);
return raw;
}
爲「測試」輸入字符串的輸出是如下按鍵上方的十六進制轉儲:
加密:
04-17 09:01:25.088 18341-18341/com.dcheeseman.hidemypics D/HIDEMYPICS: Encrypting: /storage/emulated/0/Download/bailout_5128280_GIFSoup.com-1.gif
04-17 09:01:25.088 18341-18341/com.dcheeseman.hidemypics D/HIDEMYPICS: Passphrase: test Key: ffffff85affffffe21023ffffffb7ffffffe8ffffffc8214031fffffffa5b29ffffff9affffff80
解密:
04-17 09:01:43.808 18341-18341/com.dcheeseman.hidemypics D/HIDEMYPICS: Decrypting: /storage/emulated/0/Download/bailout_5128280_GIFSoup.com-1.gif.epf
04-17 09:01:43.808 18341-18341/com.dcheeseman.hidemypics D/HIDEMYPICS: Passphrase: test Key: ffffff8331ffffffe2ffffff87ffffffe242dffffffa61cffffffc7ffffffb4ffffffa1d74ffffff9affffff9b
兩個加密和解密用的「測試」作爲密碼播種,但該函數返回2個不同的密鑰,這就是爲什麼我覺得我越來越壞 - 解密錯誤,這完全跟蹤上市如下:
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: java.io.IOException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at javax.crypto.CipherOutputStream.close(CipherOutputStream.java:136)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at com.dcheeseman.hidemypics.AESUtils.decryptFileFromUri(AESUtils.java:102)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at com.dcheeseman.hidemypics.HideMyPics.onActivityResult(HideMyPics.java:35)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.Activity.dispatchActivityResult(Activity.java:6808)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.ActivityThread.deliverResults(ActivityThread.java:4698)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.ActivityThread.handleSendResult(ActivityThread.java:4745)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.ActivityThread.access$1500(ActivityThread.java:197)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1730)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.os.Looper.loop(Looper.java:145)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6872)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at java.lang.reflect.Method.invoke(Native Method)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at java.lang.reflect.Method.invoke(Method.java:372)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
04-17 09:33:24.158 823-823/com.dcheeseman.hidemypics W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
在此先感謝您對此問題的任何幫助!
從問題中刪除未使用的代碼。 – zaph
您聲明:「2個不同的密鑰」,密鑰必須相同,因此要調試的區域是密鑰派生'getRawKey'。還要檢查IV是如何創建並傳遞給解密的,您需要研究庫文檔。 – zaph