title: Impossible to read crypt Video with AES Cipher on Android
body: <p>I have to read an encrypted video on Android device.</p>
  
  <p>I created a localhost server using <a href="http://elonen.iki.fi/code/nanohttpd/" rel="nofollow">http://elonen.iki.fi/code/nanohttpd/</a> which permits this in a very simple way.</p>
  
  <p>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)</p>
  
  <p>I tried the following: </p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>I try with CTR16 to get block of 16 bits, and to read them with a bufer of 32ko. That does not work.</p>
  
  <p>(PS : I have no problem to uncrypt picture with my method)</p>
  
  <p>Here my crypt method :</p>
  
  <pre><code>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;
  }
  </code></pre>
  
  <p>and the <code>CipherInputStreamWithData</code> I created because the method available always returns <code>0</code> with the normal <code>CipherInputStreamWithData</code>:</p>
  
  <pre><code>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;
      }
  
  }
  </code></pre>