【问题标题】:Impossible to read crypt Video with AES Cipher on Android无法在 Android 上使用 AES 密码读取加密视频
【发布时间】:2012-07-20 16:50:04
【问题描述】:

我必须在 Android 设备上阅读加密视频。

我使用http://elonen.iki.fi/code/nanohttpd/ 创建了一个本地主机服务器,它以非常简单的方式允许这样做。

我用它来阅读未加密的视频,但我一直在阅读加密的视频。 (我加密视频没有任何问题,只是为了阅读它)

我尝试了以下方法:

1- 使用简单的“AES”加密视频,当我尝试用我的服务器读取它时,我看到流媒体开始(我看到我的服务器以不同的范围回答 3 次)。 播放 3 次后,播放器说无法阅读视频。

2- 使用“AES/CTR/NoPadding”加密视频:在这种情况下,我看到我的服务器提供了第一个范围,并且一次又一次地运行,但没有视频显示。

我尝试使用 CTR16 获取 16 位块,并使用 32ko 的缓冲区读取它们。那是行不通的。

(PS:我用我的方法解图片没问题)

这是我的加密方法:

public static InputStream getUncryptInputStream(InputStream is, String pass, final long dataLen) throws Exception{
        SecretKeySpec key = new SecretKeySpec(getRawKey(pass.getBytes()), "AES");
        Cipher mCipher = Cipher.getInstance("AES/CTR/NoPadding");
        mCipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
        if(dataLen==-1){
            return new CipherInputStream(is, mCipher);
        }else{
            return new CipherInputStreamWithDataLen(is, mCipher, dataLen);
        }
}

public static OutputStream getCryptOutputStream(OutputStream os, String pass) throws Exception{
    SecretKeySpec key = new SecretKeySpec(getRawKey(pass.getBytes()), "AES");

    Cipher mCipher = Cipher.getInstance("AES/CTR/NoPadding");
    mCipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

    return new CipherOutputStream(os, mCipher);

}

private static 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;
}

还有我创建的CipherInputStreamWithData,因为可用的方法总是返回0和正常的CipherInputStreamWithData

import java.io.IOException;
import java.io.InputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;

public class CipherInputStreamWithDataLen extends CipherInputStream{

    int dataLen;

    public CipherInputStreamWithDataLen(InputStream is, Cipher mCipher, long dataLen) {
        super(is, mCipher);
        this.dataLen = (int)dataLen;
        // TODO Auto-generated constructor stub
    }

    public int available() throws IOException{
        return dataLen;
    }

}

【问题讨论】:

  • 问题来自CipherInputStream。

标签: android video encryption aes


【解决方案1】:

问题在于 CipherInputStream 跳过方法。

  1. 由于密码加密,您必须小心跳过直到最后一个 cipherBlock,然后解密最后一个 +1 个 cupherblock,以获得需要写入 BufferedOutputStream 的几个额外字节
  2. 如果 CipherInputStream 的 "available" 方法返回的值是

一般评论:在视频开始之前,需要大约 10 秒的时间来使用大型 BufferedInputStream。 有人建议使用 NDK 以原生方式对 AES 进行编码。 出于我的需要,我只需编写一个简单的 XOR。

【讨论】:

    猜你喜欢
    • 2011-12-20
    • 2012-04-08
    • 2011-10-10
    • 2021-01-13
    • 2020-10-15
    • 2016-09-22
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多