/** * 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 } } }
private void createSignature(OutputStream out) throws Exception { PGPSecretKey pgpSec = readSecretKey(); PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey( new JcePBESecretKeyDecryptorBuilder() .setProvider(getProvider()) .build("sdude".toCharArray())); PGPSignatureGenerator sGen = new PGPSignatureGenerator( new JcaPGPContentSignerBuilder(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1) .setProvider(getProvider())); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); BCPGOutputStream bOut = new BCPGOutputStream(out); InputStream fIn = new ByteArrayInputStream("Test Signature".getBytes("UTF-8")); int ch; while ((ch = fIn.read()) >= 0) { sGen.update((byte) ch); } fIn.close(); sGen.generate().encode(bOut); }
/** Creates a {@link PersonalKey} from private and public key byte buffers. */ @SuppressWarnings("unchecked") public static PersonalKey load(byte[] privateKeyData, char[] passphrase, byte[] bridgeCertData) throws KonException, IOException, PGPException, CertificateException, NoSuchProviderException { PGPSecretKeyRing secRing = new PGPSecretKeyRing(privateKeyData, PGPUtils.FP_CALC); PGPSecretKey authKey = null; PGPSecretKey signKey = null; PGPSecretKey encrKey = null; // assign from key ring Iterator<PGPSecretKey> skeys = secRing.getSecretKeys(); while (skeys.hasNext()) { PGPSecretKey key = skeys.next(); if (key.isMasterKey()) { // master key: authentication / legacy: signing authKey = key; } else { // sub keys: encryption and signing / legacy: only encryption int keyFlags = PGPUtils.getKeyFlags(key.getPublicKey()); if ((keyFlags & PGPKeyFlags.CAN_SIGN) == PGPKeyFlags.CAN_SIGN) signKey = key; else encrKey = key; } } // legacy: auth key is actually signing key if (signKey == null && authKey != null && authKey.isSigningKey()) { LOGGER.info("loading legacy key"); signKey = authKey; } if (authKey == null || signKey == null || encrKey == null) throw new KonException( KonException.Error.LOAD_KEY, new PGPException("could not found all keys in key data")); // decrypt private PGPDigestCalculatorProvider calcProv = new JcaPGPDigestCalculatorProviderBuilder().build(); PBESecretKeyDecryptor decryptor = new JcePBESecretKeyDecryptorBuilder(calcProv) .setProvider(PGPUtils.PROVIDER) .build(passphrase); PGPKeyPair authKeyPair = PGPUtils.decrypt(authKey, decryptor); PGPKeyPair signKeyPair = PGPUtils.decrypt(signKey, decryptor); PGPKeyPair encryptKeyPair = PGPUtils.decrypt(encrKey, decryptor); // X.509 bridge certificate X509Certificate bridgeCert = PGPUtils.loadX509Cert(bridgeCertData); return new PersonalKey(authKeyPair, signKeyPair, encryptKeyPair, bridgeCert); }
/** * 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(); }