Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and why decorate OutputStream with ArmoredOutputStream when using BouncyCastle

I'm pretty new to BouncyCastle and pgp. I've seen many articles and samples on the internet. Almost every encryption sample contains the code snipped below

if (armor) 
        out = new ArmoredOutputStream(out);

It seems that my local test passed with both armor and none-armor. I googled around but found few useful and the javadoc of ArmoredOutputStream only shows This is basic output stream.

So what's the difference and when to use it?

Complete code sample:

public static void encryptFile(String decryptedFilePath,
        String encryptedFilePath,
        String encKeyPath,
        boolean armor,
        boolean withIntegrityCheck)            
        throws Exception{

    OutputStream out = new FileOutputStream(encryptedFilePath);
    FileInputStream pubKey = new FileInputStream(encKeyPath);
    PGPPublicKey encKey = readPublicKeyFromCollection2(pubKey);
    Security.addProvider(new BouncyCastleProvider());

    if (armor) 
        out = new ArmoredOutputStream(out);

    // Init encrypted data generator
    PGPEncryptedDataGenerator encryptedDataGenerator =
            new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, withIntegrityCheck, new SecureRandom(),"BC");

    encryptedDataGenerator.addMethod(encKey);


    OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BUFFER_SIZE]);

    // Init compression  
    PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZIP);
    OutputStream compressedOut = compressedDataGenerator.open(encryptedOut);  

    PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
    OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, decryptedFilePath, new Date(), new byte[BUFFER_SIZE]);
    FileInputStream inputFileStream = new FileInputStream(decryptedFilePath);
    byte[] buf = new byte[BUFFER_SIZE];  
    int len;
    while((len = inputFileStream.read(buf))>0){
        literalOut.write(buf,0,len);
    }

    literalOut.close();
    literalDataGenerator.close();

    compressedOut.close();
    compressedDataGenerator.close();
    encryptedOut.close();
    encryptedDataGenerator.close();
    inputFileStream.close();
    out.close();

}
}
like image 853
Yugang Zhou Avatar asked Jun 23 '14 05:06

Yugang Zhou


2 Answers

ArmoredOutputStream uses an encoding similar to Base64, so that binary non-printable bytes are converted to something text friendly. You'd do this if you wanted to send the data over email, or post on a site, or some other text medium.

It doesn't make a difference in terms of security. There is a slight expansion of the message size though. The choice really just depends on what you want to do with the output.

like image 78
mfanto Avatar answered Nov 11 '22 21:11

mfanto


ASCII armor is a generic term that means a binary data representation as an ASCII-only text. Technically, there is a lot of ways to ascii-armor binary data, but in the cryptography-related field the PEM format is prevalent (also check this and related questions at serverfault).

The PEM is basically a Base64-encoded binary data wrapped in -----BEGIN SOMETHING----- and -----END SOMETHING----- delimiters and a set of additional headers that can contain some meta information about the binary content.

like image 32
Oleg Estekhin Avatar answered Nov 11 '22 21:11

Oleg Estekhin