/** * Create a clear sign signature over the input data. (Not detached) * * @param input the content to be signed * @param keyring the keyring * @param keyId the 4 bytes identifier of the key, in hexadecimal format * @param passphrase the passphrase to retrieve the private key * @param output the output destination of the signature */ public static void clearSign( InputStream input, InputStream keyring, String keyId, String passphrase, OutputStream output) throws IOException, PGPException, GeneralSecurityException { PGPSecretKey secretKey = getSecretKey(keyring, keyId); PGPPrivateKey privateKey = secretKey.extractPrivateKey( new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()) .build(passphrase.toCharArray())); int digest = PGPUtil.SHA1; PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), digest)); signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey); ArmoredOutputStream armoredOutput = new ArmoredOutputStream(output); armoredOutput.beginClearText(digest); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String line; while ((line = reader.readLine()) != null) { // trailing spaces must be removed for signature calculation (see // http://tools.ietf.org/html/rfc4880#section-7.1) byte[] data = trim(line).getBytes("UTF-8"); armoredOutput.write(data); armoredOutput.write(EOL); signatureGenerator.update(data); signatureGenerator.update(EOL); } armoredOutput.endClearText(); PGPSignature signature = signatureGenerator.generate(); signature.encode(new BCPGOutputStream(armoredOutput)); armoredOutput.close(); }
/** * Encodes the provided message with the private key and pass phrase set in configuration * * @param message Message to encode * @return Encoded message * @throws LRException SIGNING_FAILED if the document cannot be signed, NO_KEY if the key cannot * be obtained */ private String signEnvelopeData(String message) throws LRException { // Get an InputStream for the private key InputStream privateKeyStream = getPrivateKeyStream(privateKey); // Get an OutputStream for the result ByteArrayOutputStream result = new ByteArrayOutputStream(); ArmoredOutputStream aOut = new ArmoredOutputStream(result); // Get the pass phrase char[] privateKeyPassword = passPhrase.toCharArray(); try { // Get the private key from the InputStream PGPSecretKey sk = readSecretKey(privateKeyStream); PGPPrivateKey pk = sk.extractPrivateKey(privateKeyPassword, "BC"); PGPSignatureGenerator pgp = new PGPSignatureGenerator(sk.getPublicKey().getAlgorithm(), PGPUtil.SHA256, "BC"); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); // Clear sign the message java.util.Iterator it = sk.getPublicKey().getUserIDs(); if (it.hasNext()) { spGen.setSignerUserID(false, (String) it.next()); pgp.setHashedSubpackets(spGen.generate()); } aOut.beginClearText(PGPUtil.SHA256); pgp.initSign(PGPSignature.CANONICAL_TEXT_DOCUMENT, pk); byte[] msg = message.getBytes(); pgp.update(msg, 0, msg.length); aOut.write(msg, 0, msg.length); BCPGOutputStream bOut = new BCPGOutputStream(aOut); aOut.endClearText(); pgp.generate().encode(bOut); String strResult = result.toString("utf8"); return strResult; } catch (Exception e) { throw new LRException(LRException.SIGNING_FAILED); } finally { try { if (privateKeyStream != null) { privateKeyStream.close(); } aOut.close(); result.close(); } catch (IOException e) { // Could not close the streams } } }