我在我的项目中使用这个库来下载文件,它工作得很好。现在我希望我下载的文件和视频必须加密。这是我经过一些研究后设法编写的代码。但它给出了一个下载错误。
public static class MyStorageResolver extends DefaultStorageResolver {
String ALGORITHM = "Blowfish";
String MODE = "Blowfish/CBC/PKCS5Padding";
String IV = "!a3edr45";
String KEY = "xxxxxxxx";
Cipher cipher;
public MyStorageResolver(Context context) {
super(context, FetchCoreUtils.getFileTempDir(context));
}
@NotNull
@Override
public OutputResourceWrapper getRequestOutputResourceWrapper(@NotNull Downloader.ServerRequest request) {
try {
Key secretKey = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(IV.getBytes()));
return new OutputResourceWrapper() {
RandomAccessFile randomAccessFile = new RandomAccessFile(request.getFile(), "rw");
@Override
public void write(@NotNull byte[] byteArray, int offSet, int length) throws IOException {
randomAccessFile.write(cipher.update(byteArray, offSet, length), offSet, length);
Log.d("download", "raf writing");
}
@Override
public void setWriteOffset(long offset) throws IOException {
int AES_BLOCK_SIZE = 16;
int skip = (int) (offset % AES_BLOCK_SIZE);
long blockOffset = offset - skip;
long numberOfBlocks = blockOffset / AES_BLOCK_SIZE;
BigInteger ivForOffsetAsBigInteger = new BigInteger(1, IV.getBytes()).add(BigInteger.valueOf(numberOfBlocks));
byte[] ivForOffsetByteArray = ivForOffsetAsBigInteger.toByteArray();
IvParameterSpec computedIvParameterSpecForOffset;
if (ivForOffsetByteArray.length < AES_BLOCK_SIZE) {
byte[] resizedIvForOffsetByteArray = BigInteger.valueOf(AES_BLOCK_SIZE).toByteArray();
System.arraycopy(ivForOffsetByteArray, 0, resizedIvForOffsetByteArray, AES_BLOCK_SIZE - ivForOffsetByteArray.length, ivForOffsetByteArray.length);
computedIvParameterSpecForOffset = new IvParameterSpec(resizedIvForOffsetByteArray);
} else {
computedIvParameterSpecForOffset = new IvParameterSpec(ivForOffsetByteArray, ivForOffsetByteArray.length - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
}
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKey, computedIvParameterSpecForOffset);
} catch (InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
byte[] skipBuffer = BigInteger.valueOf(skip).toByteArray();
try {
cipher.update(skipBuffer, 0, skip, skipBuffer);
} catch (ShortBufferException e) {
e.printStackTrace();
}
randomAccessFile.seek(offset);
Log.d("download", "raf seeked");
}
@Override
public void flush() {
}
@Override
public void close() throws IOException {
randomAccessFile.close();
}
};
} catch (FileNotFoundException | NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException e) {
Log.d("download", "raf error");
e.printStackTrace();
}
return super.getRequestOutputResourceWrapper(request);
}
}
我是这样的
FetchConfiguration fetchConfiguration = new FetchConfiguration.Builder(this)
.setDownloadConcurrentLimit(2)
.enableRetryOnNetworkGain(true)
// .setNamespace("TdeskDownloader")
.enableFileExistChecks(true)
.setProgressReportingInterval(500)
.setAutoRetryMaxAttempts(3)
.setNotificationManager(new DefaultFetchNotificationManager(this) {
@Override
public void updateNotification(@NotNull NotificationCompat.Builder notificationBuilder, @NotNull DownloadNotification downloadNotification, @NotNull Context context) {
Intent intent = new Intent(getBaseContext(), DownloadsActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getBaseContext(), 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notificationBuilder
.setOnlyAlertOnce(true)
.setColorized(true)
.setNotificationSilent()
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setColor(getResources().getColor(R.color.colorAccent))
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round))
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL);
super.updateNotification(notificationBuilder, downloadNotification, context);
}
@NotNull
@Override
public Fetch getFetchInstanceForNamespace(@NotNull String namespace) {
return fetch;
}
@Override
public boolean shouldCancelNotification(@NotNull DownloadNotification downloadNotification) {
return downloadNotification.getStatus() == Status.CANCELLED;
}
})
.setHttpDownloader(new HttpUrlConnectionDownloader(Downloader.FileDownloaderType.PARALLEL))
.setStorageResolver(new MyStorageResolver(this.getApplicationContext()))
.build();
Fetch.Impl.setDefaultInstanceConfiguration(fetchConfiguration);
fetch = Fetch.Impl.getDefaultInstance();
这是错误日志:
2021-07-10 04:19:15.724 E/LibGlobalFetchLib: FileDownloader download:DownloadInfo(id=-1757988576, namespace='LibGlobalFetchLib', url='https://file-examples-com.github.io/uploads/2017/10/file-example_PDF_500_kB.pdf', file='/storage/emulated/0/Download/tdesk/file-example_PDF_500_kB.pdf', group=0, priority=HIGH, headers={}, downloaded=0, total=469513, status=DOWNLOADING, error=NONE, networkType=ALL, created=1625870930995, tag=null, enqueueAction=UPDATE_ACCORDINGLY, identifier=0, downloadOnEnqueue=true, extras={"mime":"application\/pdf"}, autoRetryMaxAttempts=0, autoRetryAttempts=3, etaInMilliSeconds=-1, downloadedBytesPerSecond=-1)
java.lang.ArrayIndexOutOfBoundsException: src.length=8 srcPos=0 dst.length=1 dstPos=8 length=8
at java.lang.System.arraycopy(Native Method)
at com.toppersdesk.app.commonUtility$MyStorageResolver$1.setWriteOffset(commonUtility.java:366)
at com.tonyodev.fetch2.downloader.ParallelFileDownloaderImpl.downloadSliceFiles(ParallelFileDownloaderImpl.kt:416)
at com.tonyodev.fetch2.downloader.ParallelFileDownloaderImpl.run(ParallelFileDownloaderImpl.kt:149)
at com.tonyodev.fetch2.downloader.DownloadManagerImpl$start$$inlined$synchronized$lambda$1.run(DownloadManagerImpl.kt:103)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
也许我犯了一些与课堂有关的基本错误。有人能帮我指出我在代码中犯的错误吗?
编辑:我将按照本期中的示例实现简历支持的密码加密。我从未使用过这个类,所以我不知道示例代码中提供的逻辑到底有什么问题。
暂无答案!
目前还没有任何答案,快来回答吧!