【问题标题】:Difference between FileOutputStream and PrintWriterFileOutputStream 和 PrintWriter 的区别
【发布时间】:2013-01-05 09:44:59
【问题描述】:

我正在我的应用程序中实施 SSL 证书和密钥。我使用 CertAndKeyGen 类创建了私钥。我正在尝试使用密码加密私钥,这是我通过 PBE 和 Cipher 类实现的。我想将加密的私钥写入 PEM 格式的文件中。我尝试使用正在工作的 FileOutputStream,但 PrintWriter 无法正常工作。

下面是我的代码,

    final CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
    keypair.generate(1024);
    final PrivateKey privKey = keypair.getPrivateKey();
    byte[] encodedprivkey = privKey.getEncoded();
    String MYPBEALG = "PBEWithSHA1AndDESede";
    String password = "test123";
    int count = 20;// hash iteration count
    Random random = new Random();
    byte[] salt = new byte[8];
    random.nextBytes(salt);
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, count);
    PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray());
    SecretKeyFactory keyFac = SecretKeyFactory.getInstance(MYPBEALG);
    SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
    Cipher pbeCipher = Cipher.getInstance(MYPBEALG);
    // Initialize PBE Cipher with key and parameters
    pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
    // Encrypt the encoded Private Key with the PBE key
    byte[] ciphertext = pbeCipher.doFinal(encodedprivkey);
    // Now construct  PKCS #8 EncryptedPrivateKeyInfo object
    AlgorithmParameters algparms = AlgorithmParameters.getInstance(MYPBEALG);
    algparms.init(pbeParamSpec);
    EncryptedPrivateKeyInfo encinfo = new EncryptedPrivateKeyInfo(algparms,ciphertext);
    byte[] encryptedPkcs8 = encinfo.getEncoded();

    // Now I am writing the encrypted private key into a file.
    // Using FileOutputStream 

    FileOutputStream out = new FileOutputStream("usingOutEncrypedPrivkey");
    out.write(Base64.encodeBase64(encryptedPkcs8, true));
    out.flush();
    out.close();

    // Using PrintWriter 
    PrintWriter pw = new PrintWriter("usingPwEncryptedPrivKey");
    pw.println("-----BEGIN "+ privKey.getAlgorithm() + " PRIVATE KEY-----");
    pw.println(Base64.encodeBase64(encryptedPkcs8));
    pw.println("-----END "+ privKey.getAlgorithm() +" PRIVATE KEY-----");
    pw.close();

以下是保存的文件,

    usingOutEncrypedPrivkey  // Which was saved using FileOutputStream

    MIICoTAbBgoqhkiG9w0BDAEDMA0ECL4xgraq2hXxAgEUBIICgFENaB8EA/kR0ymSC8vcyj1fNFbP
    iR+mXkBk7aH3eF7fpP8yqCvtN0/0VqHi/w/Z2CLgiib2s/zuiVPtWI8vsRRPXmD9PYxZp3ilLpD4
                            .....
                            .....   
    9nH8HdQf584c3sKYEErDQvJR2SmbUPtNq4cB6ocUuiOTztBqRXAHeaWavnqHFxHUT7c=


    usingPwEncryptedPrivKey  // Which was saved using PrintWriter
   -----BEGIN RSA PRIVATE KEY-----
   [B@19e3118a
   -----END RSA PRIVATE KEY-----

为什么 PrintWriter 写为“[B@19e3118a”,而不是像 FileOutputStream 这样的字节。我想使用 PrintWriter 因为我想使用 PrintWriter.println() 函数。请帮帮我。提前致谢。

【问题讨论】:

    标签: java fileoutputstream printwriter


    【解决方案1】:
    • OutputStream.write(byte[]) 将字节写入二进制数据。
    • PrintWriter.print(byte[]) 在数组上调用 toString() 并写出结果。 [B@19e3118a 是数组的 toString() 表示形式。

    鉴于字符串仅包含 ASCII 字符,您可以在数组上使用 String(byte[]),并打印结果。

    或者,如果您使用 Apache Commons Base64 类,您应该简单地使用 encodeBase64String() 方法而不是 encodeBase64() [感谢 @SimonC]。

    【讨论】:

    • 是的。 encodeBase64String() 是一个不错的选择,但是它不会对数据进行分块(在每个第 77 个字符后换行)。在使用 encodeBase64() 的情况下,还有第二个参数,我们可以在其中传递 true 或 false 进行分块。任何其他方式来实现这一目标?用换行符分块和写它?
    【解决方案2】:

    [B@19e3118a 是在字节数组上调用toString() 的结果。我不知道您使用的是哪个 Base64 类,但如果您想使用 Writer,您应该找到一个将字节数组编码为字符串,而不是将字节数组编码为其他字节数组的类。

    【讨论】:

    【解决方案3】:

    两种方式

    1. 使用 OutputStream.write(),然后自己拆分行。
    2. 使用PrintWrite.println(),那么你需要将原始字节编码成String并自己分割行...

    【讨论】:

      猜你喜欢
      • 2015-12-24
      • 2011-02-18
      • 2012-12-13
      • 1970-01-01
      • 2021-08-06
      • 2012-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多