2010-02-08 40 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