次の基準を使用して暗号化されたJavaでファイルを復号化するタスクがあります。
128ビットキー、ECBモード、PKCS7パディングを備えたAES暗号化アルゴリズム。暗号化されたファイル形式は次のとおりです。-最初のバイトは16進数0x31–使用する暗号化方式を指定します(AESの場合は1)-その後に入力ファイルの暗号化されたバイトが続きます
ファイルもダウンロードする必要があるので、これまでの試みは次のとおりです。
ダウンロードコード。必須ではなく、暗号化されていないため、ここでは最初のバイトをスキップします。
final String PATH = "/sdcard/" + IMEI + ".xml"; //put the downloaded file here
try {
URL url = new URL(context.getString(R.string.xml_feed) + IMEI + ".xml");
enc_File = new File(PATH);
long startTime = System.currentTimeMillis();
/* Open a connection to that URL. */
URLConnection ucon = url.openConnection();
/*
* Define InputStreams to read from the URLConnection.
*/
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
/*
* Read bytes to the Buffer until there is nothing more to read(-1). */
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
bis.skip(1);
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(enc_File);
fos.write(baf.toByteArray());
fos.close();
} catch (IOException e) {
}
}
これにより、暗号化されたファイルがダウンロードされるので、次のコードを使用してこのファイルを復号化しようとします。
String bytes = toHex("the 16 bit key");
Key skeySpec = new SecretKeySpec(toByte(bytes), "AES");
Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding");
byte[] buf = new byte[1024];
// Bytes read from in will be decrypted
InputStream inCipher = new FileInputStream(enc_File);
OutputStream outCipher = new FileOutputStream(cipherFile);
c.init(Cipher.DECRYPT_MODE, skeySpec);
inCipher = new CipherInputStream(inCipher, c); // Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = inCipher.read(buf)) >= 0) {
outCipher.write(buf, 0, numRead);
}
outCipher.close();
上記は私に新しいファイルのdecrytedデータを与えるはずです。
そして、SecretKeySpecのバイト形式のキーを作成するためにそのコードで使用されるutilメソッドは次のとおりです。
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();
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));
}
public static String toHex(String txt) {
return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
ただし、これにより現在、次の例外が発生します。
10-12 11:19:26.337: WARN/System.err(5376): java.io.IOException: last block incomplete in decryption
暗号化されたファイルは正常にダウンロードされ、復号化は実行されますが、上記の例外が発生し、復号化する必要のあるファイルをチェックすると、ファイルの最初の行が正しく復号化され、次の数行のごく一部が残りの部分にジャンクが返されることがわかります。
問題をどこで探すべきかわからないので、私はこれで立ち往生しています、誰かが助けることができますか?または、例外を引き起こしている可能性のある方向に私を向けますか?
追加情報:
10-12 15:30:37.291: WARN/System.err(6898): at com.mypackage.net.SettingsProvisioner.getRoutingDoc(SettingsProvisioner.java:217)
上記の行は、log cat(stacktrace)の例外からのものです。
そして、このコード行で例外が発生していることを示しています。
while ((numRead = inCipher.read(buf)) >= 0) {