无法在Android上使用AES Cipher读取crypt视频

时间:2012-07-20 16:50:05

标签: android video encryption aes

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

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

我用它来阅读未加密的视频,但我仍然坚持阅读加密的视频。 (我加密视频没有任何问题,只是为了阅读它)

我尝试了以下内容:

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

}

1 个答案:

答案 0 :(得分:1)

问题是因为CipherInputStream跳过方法。

  1. 由于密码加密,你必须小心跳过直到最后一个cipherBlock然后解密最后的+ 1个cupherblock以获得你需要写入BufferedOutputStream的几个额外字节
  2. 如果来自CipherInputStream的“available”方法返回的值是<对于要跳过的字节数,skip方法将跳过的最大字节数将等于“available”方法返回的值。
  3. 一般注释:在视频开始之前需要大约10秒的大型BufferedInputStream。 有人建议使用NDK以原生代码对AES进行编码。 根据我的需要,我只需编写一个简单的XOR代码。