Reputation: 115
I have to read an encrypted video on Android device.
I created a localhost server using http://elonen.iki.fi/code/nanohttpd/ which permits this in a very simple way.
I achieve with it to read unencrypted videos but I am stuck at reading the encrypted videos. (I don't have any trouble to encrypt the video, just to read it)
I tried the following:
1- To encrypt video using a simple "AES", and when I try to read it with my server, I see the streaming starts (I see my server answering 3 times with various range). After 3 times the player says that is impossible to read the video.
2- To encrypt the video using "AES/CTR/NoPadding": in that case, I see my server that delivers the first range and that iss running again and again and again but no video displays.
I try with CTR16 to get block of 16 bits, and to read them with a bufer of 32ko. That does not work.
(PS : I have no problem to uncrypt picture with my method)
Here my crypt method :
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;
}
and the CipherInputStreamWithData
I created because the method available always returns 0
with the normal 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;
}
}
Upvotes: 1
Views: 1148
Reputation: 115
The problem was because of the CipherInputStream skip method.
General Comment : It takes arround 10s with a large BufferedInputStream before a video starts. Some people suggests to use the NDK to code the AES in native. For my need I just code a simple XOR.
Upvotes: 1