代码之家  ›  专栏  ›  技术社区  ›  Mark

我的密码输出流无声地失败了

  •  4
  • Mark  · 技术社区  · 14 年前

    我试图用一个公钥加密Java中的一些二进制数据,如在这个有用的页面上所描述的: http://www.junkheap.net/content/public_key_encryption_java

    按照页面的指示,我使用以下命令创建了公钥和私钥:

    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();
    
    
        }
    }
    

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

    我做错什么了?

    1 回复  |  直到 14 年前
        1
  •  5
  •   President James K. Polk    14 年前

    CipherOutputStream倾向于吞咽由它包装的密码和OutputStream对象生成的异常。Sun RSA实现的加密不会超过M-11字节,其中M是模的长度(以字节为单位)。这对于默认的pkcs1padding是正确的,除非您真正知道自己在做什么,否则您应该始终使用它。您可以指定nopadding,从而获得完整的m字节。

    RSA不是加密批量数据的正确选择。用RSA加密数据的一般方法是生成随机对称会话密钥。 K .例如,AES密钥,使用对称算法加密数据 K ,然后使用所有接收器的RSA密钥加密k。