2010-02-08 36 views
4

我想,因为这很有用页面上的方法在Java中一些二进制数据使用公钥加密: http://www.junkheap.net/content/public_key_encryption_java我CipherOutputStream静静地失败

所指示的页面,我创建使用命令公钥和私钥:

openssl genrsa -aes256 -out private.pem 2048 
openssl rsa -in private.pem -pubout -outform DER -out public.der 

现在我保存了一个小程序加密一些数据:

public class Rsa { 

    public static void main(String[] args) throws Exception, IOException { 
     File keyFile = new File("public.der"); 
     byte[] encodedKey = new byte[(int) keyFile.length()]; 

     new FileInputStream(keyFile).read(encodedKey); 

     X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey); 

     KeyFactory kf = KeyFactory.getInstance("RSA"); 
     PublicKey pk = kf.generatePublic(publicKeySpec); 

     Cipher rsa = Cipher.getInstance("RSA"); 

     rsa.init(Cipher.ENCRYPT_MODE, pk); 

     FileOutputStream fileOutputStream = new FileOutputStream(
       "encrypted.rsa"); 
     OutputStream os = new CipherOutputStream(fileOutputStream, rsa); 

     byte[] raw = new byte[245]; 
     raw[0] = 4; 

     os.write(raw); 
     os.flush(); 
     os.close(); 


    } 
} 

上面的代码工作,但WH我将字节数组的大小更改为246,它会生成一个零长度的文件!

我在做什么错?

回答

5

CipherOutputStream倾向于吞食由其包装的Cipher和OutputStream对象生成的异常。 Sun RSA实现不会加密超过M-11个字节,其中M是模数的字节长度。这对于默认的PKCS1Padding来说是正确的,除非你真的知道你在做什么,否则这是你应该始终使用的。您可以指定NoPadding并从而获得完整的M字节。

RSA不是加密批量数据的正确选择。用RSA加密数据的普遍接受的方法是生成随机对称会话密钥K。例如AES密钥,使用对称算法使用K加密数据,然后使用所有收件人的RSA密钥对K进行加密。

+0

感谢格雷格 - 我希望我知道,4小时前! – Mark 2010-02-08 13:28:41