Marshmallow中的加密失败

时间:2016-04-19 04:37:01

标签: android

我正在尝试加密和解密来自SD卡的数据我尝试使用代码并在低版本设备中正常工作但我在marshmallow中遇到一个例外。

  04-19 09:56:50.428: W/System.err(15137): javax.crypto.BadPaddingException: pad block corrupted
  04-19 09:56:50.432: W/System.err(15137):  at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal(BaseBlockCipher.java:1011)
  04-19 09:56:50.432: W/System.err(15137):  at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:849)
  04-19 09:56:50.432: W/System.err(15137):  at javax.crypto.Cipher.doFinal(Cipher.java:1502)
  04-19 09:56:50.432: W/System.err(15137):  at com.example.encryptaudio.CryptoFile.decrypt(CryptoFile.java:34)
  04-19 09:56:50.432: W/System.err(15137):  at com.example.encryptaudio.MainActivity$2.onClick(MainActivity.java:116)
  04-19 09:56:50.432: W/System.err(15137):  at android.view.View.performClick(View.java:5201)
  04-19 09:56:50.432: W/System.err(15137):  at android.view.View$PerformClick.run(View.java:21163)
  04-19 09:56:50.432: W/System.err(15137):  at android.os.Handler.handleCallback(Handler.java:746)
  04-19 09:56:50.432: W/System.err(15137):  at android.os.Handler.dispatchMessage(Handler.java:95)
  04-19 09:56:50.432: W/System.err(15137):  at android.os.Looper.loop(Looper.java:148)
  04-19 09:56:50.432: W/System.err(15137):  at android.app.ActivityThread.main(ActivityThread.java:5443)
  04-19 09:56:50.432: W/System.err(15137):  at java.lang.reflect.Method.invoke(Native Method)
  04-19 09:56:50.432: W/System.err(15137):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)

我遵循的代码是 加密

CryptoFile simpleCrypto = new CryptoFile();                

try {
     // encrypt audio file send as second argument and corresponding key in first argument.
       incrept = simpleCrypto.encrypt(KEY, getAudioFile());                  

       //Store encrypted file in SD card of your mobile with name vincent.mp3.

      FileOutputStream fos = new FileOutputStream(new File("/sdcard/vincent.mp3"));
            fos.write(incrept);
            fos.close();

  } catch (Exception e) { 
      e.printStackTrace();
  }

}

解密

CryptoFile simpleCrypto = new CryptoFile();             

      try {

    // decrypt the file here first argument is key and second is encrypted file which we get from SD card.
    decrpt = simpleCrypto.decrypt(KEY, getAudioFileFromSdCard());
//play decrypted audio file.
    playMp3(decrpt);                    

 } catch (Exception e) {
     e.printStackTrace();
 }
}

Crypt.java

public class CryptoFile {

public  byte[] encrypt(String seed, byte[] cleartext) throws Exception {           

        byte[] rawKey = getRawKey(seed.getBytes());

    byte[] result = encrypt(rawKey, cleartext);

  //  return toHex(result);
    return result;
} 
public  byte[] decrypt(String seed, byte[] encrypted) throws Exception {

    byte[] rawKey = getRawKey(seed.getBytes());

    byte[] enc = encrypted;

    byte[] result = decrypt(rawKey, enc); 

    return result;     }

//done
 private  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  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  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;

}

}

1 个答案:

答案 0 :(得分:0)

AES密钥应包含随机数据。如果将它们存储为String,则可能会丢失信息。 您也没有在加密或解密中指定编码类型。

<强>加密

 encryptedText = c.doFinal(clearText.getBytes("UTF-8"));
 return Base64.encodeToString(encryptedText, Base64.DEFAULT);

<强>解密

clearText = c.doFinal(Base64.decode(encryptedText, Base64.DEFAULT));
return new String(clearText, "UTF-8");