我做得对还是有错?我仍在尝试实施的测试程序正在运行,没有任何异常或错误。但它没有做它必须做的事情,我找不到问题。
以下是尝试解密的Android代码:
private static final int IO_BUFFER_SIZE = 4 * 1024;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
AssetManager am = this.getAssets();
InputStream is = am.open("2000_1.jpg_encrypted"); // get the encrypted image from assets folder
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[IO_BUFFER_SIZE];
int read;
while ((read = is.read(b)) != -1) { //convert inputstream to bytearrayoutputstream
baos.write(b, 0, read);
}
//START
long start = System.currentTimeMillis()/1000L; // start
//byte[] keyStart = "MARTIN_123_MARTIN_123".getBytes(); // specific key value
KeyGenerator kgen = KeyGenerator.getInstance("AES/CBC/PKCS5Padding"); //aes
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
//sr.setSeed(keyStart);
kgen.init(128, sr);
//SecretKey skey = kgen.generateKey();
//byte[] key = skey.getEncoded();
byte[] key = "MARTIN_123_MARTIN_123".getBytes("UTF-8");
byte[] iv = "1234567890123456".getBytes("UTF-8");
byte[] decryptedData = decrypt(key, iv, b);
//END
long end = System.currentTimeMillis()/1000L; // end
Log.d("TEST","Time start "+ String.valueOf(start)); //showing the strat in ms
Log.d("TEST","Time end "+ String.valueOf(end)); //showing the end in ms
Bitmap bitmap = BitmapFactory.decodeByteArray(decryptedData , 0, decryptedData .length); //decoding bytearrayoutputstream to bitmap
//String filepath = Environment.getExternalStorageDirectory()+"bitmap";
FileOutputStream fos = new FileOutputStream("sdcard/DCIM/100ANDRO");
fos.write(decryptedData);
fos.close();
is.close(); // close the inputstream
baos.close(); // close the bytearrayoutputstream
}
catch(Exception e){
e.fillInStackTrace();
}
}
//decrypt
private byte[] decrypt(byte[] raw, byte[] iv, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
以下是加密的PHP代码:
$folder = $this->getConfiguration()->getAppRootDir() . '/temp_encryption_testing/';
$files = array(
'007FRAMESUPERIOR.jpg',
'2000_1.jpg',
'APLICACIONdescargaliga.jpg',
'APPCOMMENTS.pdf',
'AUDIOVISUALFOTO02.jpg'
);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "MARTIN_123_MARTIN_123";
foreach($files as $file)
{
$input_file = $folder . $file;
$text = file_get_contents($input_file);
//$text = "Meet me at 11 o'clock behind the monument.";
echo strlen($text) . "\n";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
file_put_contents($input_file . '_encrypted', $crypttext);
}
任何帮助将不胜感激:)
答案 0 :(得分:3)
您正尝试使用随机生成的密钥进行解密(将种子添加到SecureRandom
仅补充随机状态)。这肯定会失败。
如果"MARTIN_123_MARTIN_123".getBytes()
是你的密钥(或者更确切地说:它的前16个字节),你应该直接将它传递给你的decrypt-method:
byte[] decryptedData = decrypt(keyStart,b);
好的,从您的评论中,我可以看到您正在使用PHP加密:mcrypt使用AES-256 / ECB / ZeroBytePadding(零字节填充隐含在mcrypt中)。
首先:ECB不是安全模式 - especially for images(尽管JPG可能不如BMP那么糟糕)。如果您决定更改为CBC,请记住您需要传输IV,f.x。通过将其添加到加密数据。但是,如果您想要解密CBC,则需要在Cipher.getInstance()
- 来电(当前使用AES/CBC/PKCS5Padding
)中进行说明。
除非您知道数据的长度,否则无法真正删除零字节填充。因此,您必须在加密数据之前传输长度或添加PKCS#7填充。
最后:您使用AES-256进行加密。它使用32字节密钥。根据{{3}},如果密钥太短,它会增加\ 0s,所以你要么必须使用实际的32字节密钥,要么将\ 0s添加到Android端。
在Android端将代码更改为:
byte[] key = "MARTIN_123456789".getBytes("UTF-8");
byte[] iv = "1234567890123456".getBytes("UTF-8");
byte[] decryptedData = decrypt(key, iv, b);
private byte[] decrypt(byte[] raw, byte[] iv, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivspec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
在PHP方面:
function addpadding($string, $blocksize = 16){
$len = strlen($string);
$pad = $blocksize - ($len % $blocksize);
$string .= str_repeat(chr($pad), $pad);
return $string;
}
$key = "MARTIN_123456789";
$iv = "1234567890123456"
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, addpadding($text), MCRYPT_MODE_CBC, $iv);