/** * Reads private key from the provided InputStream * * @param input InputStream of the private key * @return PGPSecretKey * @throws LRException NO_KEY error if the key cannot be obtained from the input stream */ private PGPSecretKey readSecretKey(InputStream input) throws LRException { PGPSecretKeyRingCollection pgpSec; try { pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input)); } catch (Exception e) { throw new LRException(LRException.NO_KEY); } java.util.Iterator keyRingIter = pgpSec.getKeyRings(); while (keyRingIter.hasNext()) { PGPSecretKeyRing keyRing = (PGPSecretKeyRing) keyRingIter.next(); java.util.Iterator keyIter = keyRing.getSecretKeys(); while (keyIter.hasNext()) { PGPSecretKey key = (PGPSecretKey) keyIter.next(); if (key.isSigningKey()) { return key; } } } throw new LRException(LRException.NO_KEY); }
/** * 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 } } }