gpt4 book ai didi

java - 在android中使用AES CTR模式随机访问InputStream

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:44 25 4
gpt4 key购买 nike

我无法找到用于随机访问的 AES CTR 加密的任何工作示例。有人可以指导我如何在 CTR MODE 中使用计数器以及如何实现跳转到流中的特定位置吗?

默认流实现 (CipherInputStream) 不会跳过流,它会破坏纯文本。

我正在尝试解密存储在 Android SD 卡上的加密视频文件。嵌入式 HTTP 文件服务器即时对其进行解密。一切正常,直到用户在视频中执行搜索:视频立即停止,因为它收到损坏的视频流。

我正在使用以下代码来初始化和加密/解密流(为了简单起见,我对 key 进行了硬编码。它不会在生产中进行硬编码)

    ByteBuffer bb = ByteBuffer.allocate(16);
bb.put("1234567891230000".getBytes());
byte[] ivString = bb.array();

// INITIALISATION
String keyString = "1234567812345678";
IvParameterSpec iv = new IvParameterSpec(ivString);
SecretKeySpec keySpec = new SecretKeySpec(keyString.getBytes(), "AES");

// FOR ENCRYPTION
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivString));
Inputstream encrypted_is = new CipherInputStream(in, cipher);

// FOR DECRYPTION
cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivString));
Inputstream decrypted_is = new CipherInputStream(in, cipher);

最佳答案

您不应该使用流来实现它。流用于顺序访问数据。跳跃应该只用于向前跳跃一小段距离,而标记/重置只能用于向后跳跃一小段距离。

使用文件 map可能是最有效的。对于稍微简单但效率较低的方法,您可以使用 RandomAccessFile反而。此外,您还应该使用 Cipher.getInstance("AES/CTR/NoPadding"),使用设置为您在文件中开始位置期望的计数器的“IV”。


使用带有偏移量的 CTR 的示例代码:

private static final int AES_BLOCK_SIZE = 16;

public static final void jumpToOffset(final Cipher c,
final SecretKey aesKey, final IvParameterSpec iv, final long offset) {
if (!c.getAlgorithm().toUpperCase().startsWith("AES/CTR")) {
throw new IllegalArgumentException(
"Invalid algorithm, only AES/CTR mode supported");
}

if (offset < 0) {
throw new IllegalArgumentException("Invalid offset");
}

final int skip = (int) (offset % AES_BLOCK_SIZE);
final IvParameterSpec calculatedIVForOffset = calculateIVForOffset(iv,
offset - skip);
try {
c.init(Cipher.ENCRYPT_MODE, aesKey, calculatedIVForOffset);
final byte[] skipBuffer = new byte[skip];
c.update(skipBuffer, 0, skip, skipBuffer);
Arrays.fill(skipBuffer, (byte) 0);
} catch (ShortBufferException | InvalidKeyException
| InvalidAlgorithmParameterException e) {
throw new IllegalStateException(e);
}
}

private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv,
final long blockOffset) {
final BigInteger ivBI = new BigInteger(1, iv.getIV());
final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset
/ AES_BLOCK_SIZE));

final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray();
final IvParameterSpec ivForOffset;
if (ivForOffsetBA.length >= AES_BLOCK_SIZE) {
ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - AES_BLOCK_SIZE,
AES_BLOCK_SIZE);
} else {
final byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE];
System.arraycopy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE
- ivForOffsetBA.length, ivForOffsetBA.length);
ivForOffset = new IvParameterSpec(ivForOffsetBASized);
}

return ivForOffset;
}

关于java - 在android中使用AES CTR模式随机访问InputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23743842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com