2013-04-09 127 views
0

我正在开发iPad应用程序并使用RNCryptor进行设备上的加密和解密。这种加密格式有一个Java版本,其格式为JNCryptor如何使用JNCryptor加密InputStream

我现在有数据要从InputStream中读取,但我想在数据读取之前对其进行加密。我找到了一个名为CipherInputStream的课程,这看起来完全符合我的要求。唯一的是,我需要一个Cipher(和Provider)来指定加密方法,我不知道该怎么做。甚至有可能定义一个自定义提供程序?

有没有人有使用JNCryptor加密InputStream的替代方法的建议?

+0

我会,谢谢:) 现在我写了自己的代码,但如果像我可以调用的“更新”方法,而不是必须做所有事情,那将是很好的。我认为我现在可以使用的图书馆唯一的方法是用于代码生成,哈哈。 我已经在这个问题的答案中发布了我的解决方案,您可能可以使用它:) – Johanneke 2013-04-16 13:11:55

回答

1

在我最后写一个类来读取的InputStream,同时对数据进行加密的部分,并写入到PipedOutputStream结束。这个PipedOutputStream然后连接到一个PipedInputStream,我最终返回。加密并写入PipedOutputStream发生在单独的线程上以避免死锁。

PipedInputStream pin = new PipedInputStream(); 
PipedOutputStream pout = new PipedOutputStream(pin); 
EncryptionPipe pipe = new EncryptionPipe(5, pout, in, cipher, mac, metaData); 
//EncryptionPipe(int interval, OutputStream out, InputStream in 
//    ,Cipher cipher, Mac mac, byte[] metaData) 
pipe.start(); 
return pin; 

而且在EncryptionPipe:

public class EncryptionPipe extends Thread { 
    ... 
    @Override 
    public void run() { 
     try { 
      mac.update(metaData); 
      out.write(metaData); 

      byte[] buf = new byte[1024]; 
      int bytesRead = 0; 
      byte[] crypted; 
      byte[] hmac; 
      while ((bytesRead = in.read(buf)) != -1) { 
       if (bytesRead < buf.length) { 
        //the doFinal methods add padding if necessary, important detail! 
        crypted = cipher.doFinal(buf, 0, bytesRead); 
        hmac = mac.doFinal(crypted); 

        ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 
        bytes.write(crypted); 
        bytes.write(hmac); 
        crypted = bytes.toByteArray(); 
        bytesRead = crypted.length; 
        bytes.close(); 
       } else { 
        crypted = cipher.update(buf, 0, bytesRead); 
        mac.update(crypted, 0, bytesRead); 
       } 
       out.write(crypted, 0, bytesRead); 
       synchronized (this) { 
        this.wait(interval); 
       } 
      } 
      out.close(); 
      ... 
     } 
    } 
} 
0

您可以使用默认的Java提供程序。要实例你可以使用

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding") 

这使用AESCipher Block Chaining mode一个密码。 CBC只能工作在16个字节的倍数上,所以你也可以指定一种方法将输入填充到16个字节的倍数。

Here is some more sample AES code,让你开始

+0

那么,与RNCryptor相同的加密方法是什么?因为我需要用该库解密iPad上的数据。 – Johanneke 2013-04-10 07:29:50

+0

我研究过它,我认为我应该能够用密码来模仿RNCryptor的加密方法,但我需要RNCryptor的特定格式来解密它的客户端。我开始认为我可能需要将数据读入内存并将加密数据输出到管道输出流或其他东西... – Johanneke 2013-04-10 08:10:57

+0

或者我应该只使用SSL,doh – Johanneke 2013-04-10 09:23:56