static String signArmoredAscii(PGPPrivateKey privateKey, String data, int signatureAlgo) throws IOException, PGPException { String signature = null; final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), signatureAlgo)); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); ByteArrayOutputStream signatureOutput = new ByteArrayOutputStream(); try( BCPGOutputStream outputStream = new BCPGOutputStream( new ArmoredOutputStream(signatureOutput)) ) { Utils.processStringAsStream(data, new StreamHandler() { @Override public void handleStreamBuffer(byte[] buffer, int offset, int length) throws IOException { signatureGenerator.update(buffer, offset, length); } }); signatureGenerator.generate().encode(outputStream); } signature = new String(signatureOutput.toByteArray(), "UTF-8"); return signature; }
static String signArmoredAscii(PGPPrivateKey privateKey, byte[] data, int signatureAlgo) throws IOException, PGPException { String signature = null; final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), signatureAlgo)); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); ByteArrayOutputStream signatureOutput = new ByteArrayOutputStream(); try( BCPGOutputStream outputStream = new BCPGOutputStream( new ArmoredOutputStream(signatureOutput)) ) { Utils.processByteArrayAsStream(data, new StreamHandler() { @Override public void handleStreamBuffer(byte[] buffer, int offset, int length) throws IOException { signatureGenerator.update(buffer, offset, length); } }); signatureGenerator.generate().encode(outputStream); } signature = new String(signatureOutput.toByteArray(), "UTF-8"); return signature; }
public PGPSignatureGenerator createSignatureGenerator() { try { PGPSignatureGenerator generator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1)); generator.init(PGPSignature.BINARY_DOCUMENT, privateKey); return generator; } catch (PGPException e) { throw new UncheckedException(e); } }
/** * Create a signer that wraps {@code os} and generates a detached signature using * {@code signingKey}. After closing, you should call {@link #getSignature()} to get the detached * signature. * * @param os is the upstream {@link OutputStream} which is not closed by this object * @throws RuntimeException to rethrow {@link PGPException} */ public RydePgpSigningOutputStream( @WillNotClose OutputStream os, PGPKeyPair signingKey) { super(os, false, -1); try { signer = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256)); signer.init(BINARY_DOCUMENT, signingKey.getPrivateKey()); } catch (PGPException e) { throw new RuntimeException(e); } addUserInfoToSignature(signingKey.getPublicKey(), signer); }
@Test public void testSignVerify_Detached() throws Exception { // Load the keys. PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY); PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey()); // Sign the data and write signature data to "signatureFile". // Note: RSA_GENERAL will encrypt AND sign. RSA_SIGN and RSA_ENCRYPT are deprecated. PGPSignatureGenerator signer = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256)); signer.init(PGPSignature.BINARY_DOCUMENT, privateKey); addUserInfoToSignature(publicKey, signer); signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); ByteArrayOutputStream output = new ByteArrayOutputStream(); signer.generate().encode(output); byte[] signatureFileData = output.toByteArray(); logger.info(".sig file data: " + dumpHex(signatureFileData)); // Load algorithm information and signature data from "signatureFileData". PGPSignature sig; try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); assertThat(sigList.size()).isEqualTo(1); sig = sigList.get(0); } // Use "onePass" and "sig" to verify "publicKey" signed the text. sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); sig.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); assertThat(sig.verify()).isTrue(); // Verify that they DIDN'T sign the text "hello monster". sig.init(new BcPGPContentVerifierBuilderProvider(), publicKey); sig.update("hello monster".getBytes(UTF_8)); assertThat(sig.verify()).isFalse(); }
protected void testInit () throws IOException { if ( this.initialized ) { return; } this.initialized = true; try { this.signatureGenerator = new PGPSignatureGenerator ( new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), this.digestAlgorithm ) ); this.signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey ); this.armoredOutput = new ArmoredOutputStream ( this.stream ); if ( this.version != null ) { this.armoredOutput.setHeader ( "Version", this.version ); } if ( this.inline ) { this.armoredOutput.beginClearText ( this.digestAlgorithm ); } } catch ( final PGPException e ) { throw new IOException ( e ); } }
@Override public void feedHeader ( final ByteBuffer header ) { try { final BcPGPContentSignerBuilder contentSignerBuilder = new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), this.hashAlgorithm ); final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator ( contentSignerBuilder ); signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey ); if ( header.hasArray () ) { signatureGenerator.update ( header.array (), header.position (), header.remaining () ); } else { final byte[] buffer = new byte[header.remaining ()]; header.get ( buffer ); signatureGenerator.update ( buffer ); } this.value = signatureGenerator.generate ().getEncoded (); logger.info ( "RSA HEADER: {}", this.value ); } catch ( final Exception e ) { throw new RuntimeException ( e ); } }
/** * creates and initializes a PGP Key Ring Generator * * @param userId * the user id to use * @param password * the password used for the private key * @param keySize * the key size used for the keys * @return the initialized key ring generator or null if something goes wrong */ private PGPKeyRingGenerator createKeyRingGenerator(String userId, String password, int keySize) { LOGGER.trace("createKeyRingGenerator(String, String, int)"); LOGGER.trace("User ID: {}, Password: {}, Key Size: {}", userId, password == null ? "not set" : "********", keySize); PGPKeyRingGenerator generator = null; try { LOGGER.debug("Creating RSA key pair generator"); RSAKeyPairGenerator generator1 = new RSAKeyPairGenerator(); generator1.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), getSecureRandom(), keySize, 12)); LOGGER.debug("Generating Signing Key Pair"); BcPGPKeyPair signingKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, generator1.generateKeyPair(), new Date()); LOGGER.debug("Generating Encyption Key Pair"); BcPGPKeyPair encryptionKeyPair = new BcPGPKeyPair(PGPPublicKey.RSA_ENCRYPT, generator1.generateKeyPair(), new Date()); LOGGER.debug("Generating Signature Key Properties"); PGPSignatureSubpacketGenerator signatureSubpacketGenerator = new PGPSignatureSubpacketGenerator(); signatureSubpacketGenerator.setKeyFlags(false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER); signatureSubpacketGenerator.setPreferredSymmetricAlgorithms(false, getPreferredEncryptionAlgorithms()); signatureSubpacketGenerator.setPreferredHashAlgorithms(false, getPreferredHashingAlgorithms()); signatureSubpacketGenerator.setPreferredCompressionAlgorithms(false, getPreferredCompressionAlgorithms()); LOGGER.debug("Generating Encyption Key Properties"); PGPSignatureSubpacketGenerator encryptionSubpacketGenerator = new PGPSignatureSubpacketGenerator(); encryptionSubpacketGenerator.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); LOGGER.info("Creating PGP Key Ring Generator"); generator = new PGPKeyRingGenerator(PGPPublicKey.RSA_SIGN, signingKeyPair, userId, new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1), signatureSubpacketGenerator.generate(), null, new BcPGPContentSignerBuilder(PGPPublicKey.RSA_SIGN, HashAlgorithmTags.SHA256), new BcPBESecretKeyEncryptorBuilder(getEncryptionAlgorithm()).build(password.toCharArray())); generator.addSubKey(encryptionKeyPair, encryptionSubpacketGenerator.generate(), null); } catch (PGPException e) { LOGGER.error("{}", e.getMessage()); generator = null; } return generator; }
@Override public void sign ( final InputStream in, final OutputStream out, final boolean inline ) throws Exception { final int digest = HashAlgorithmTags.SHA1; final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator ( new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), digest ) ); signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey ); final ArmoredOutputStream armoredOutput = new ArmoredOutputStream ( out ); if ( inline ) { armoredOutput.beginClearText ( digest ); } final byte[] buffer = new byte[4096]; int rc; while ( ( rc = in.read ( buffer ) ) >= 0 ) { if ( inline ) { armoredOutput.write ( buffer, 0, rc ); } signatureGenerator.update ( buffer, 0, rc ); } armoredOutput.endClearText (); final PGPSignature signature = signatureGenerator.generate (); signature.encode ( new BCPGOutputStream ( armoredOutput ) ); armoredOutput.close (); }
public SecretKey generateKeyPair(final String id, final char[] pass) throws CryptoException { try { // This object generates individual key-pairs. final RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 2048, 12)); // First create the master (signing) key with the generator. final PGPKeyPair keyPair = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date()); // Add a self-signature on the id final PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator(); signhashgen.setKeyFlags(true, KeyFlags.CERTIFY_OTHER | KeyFlags.SIGN_DATA | KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); signhashgen.setPreferredCompressionAlgorithms(false, new int[] { CompressionAlgorithmTags.ZIP }); signhashgen.setPreferredHashAlgorithms(false, new int[] { HashAlgorithmTags.SHA1 }); signhashgen.setPreferredSymmetricAlgorithms(false, new int[] { SymmetricKeyAlgorithmTags.AES_256 }); signhashgen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); // Create a signature on the encryption subkey. final PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator(); enchashgen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); // Objects used to encrypt the secret key. // Finally, create the keyring itself. The constructor // takes parameters that allow it to generate the self // signature. final PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); final PBESecretKeyEncryptor secretKeyEncryptor = new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_128, sha1Calc).build(pass); final BcPGPContentSignerBuilder contentSigner = new BcPGPContentSignerBuilder(keyPair.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1); final PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, keyPair, id, sha1Calc, signhashgen.generate(), null, contentSigner, secretKeyEncryptor); // return new SimpleKeyPair(new BcPGPPublicKey(publicKeyRing.getPublicKey()), return new BcPGPSecretKey(keyRingGen.generateSecretKeyRing().getSecretKey()); } catch (final Exception e) { throw new CryptoException(e); } }
private PGPSignatureGenerator getSignatureGenerator(UnlockedMasterKey owner) throws PGPException { final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(owner.getPublicKey().getAlgorithm(), hashAlgorithm.value())); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, owner.getPrivateKey()); final PGPSignatureSubpacketGenerator signatureMetaData = new PGPSignatureSubpacketGenerator(); signatureMetaData.setSignerUserID(false, owner.getUserID()); signatureGenerator.setHashedSubpackets(signatureMetaData.generate()); return signatureGenerator; }
/** * Creates a clear sign signature over the input data. (Not detached) * * @param input the content to be signed * @param output the output destination of the signature */ public void clearSign(InputStream input, OutputStream output) throws IOException, PGPException, GeneralSecurityException { PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), digest)); signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey); ArmoredOutputStream armoredOutput = new ArmoredOutputStream(output); armoredOutput.beginClearText(digest); LineIterator iterator = new LineIterator(new InputStreamReader(input)); while (iterator.hasNext()) { String line = iterator.nextLine(); // 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); if (iterator.hasNext()) { signatureGenerator.update(EOL); } } armoredOutput.endClearText(); PGPSignature signature = signatureGenerator.generate(); signature.encode(new BCPGOutputStream(armoredOutput)); armoredOutput.close(); }
/** * Creates a detached clear sign signature over the input data. * * @param input the content to be signed * @param output the output destination of the signature */ public void clearSignDetached(InputStream input, OutputStream output) throws IOException, PGPException, GeneralSecurityException { PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(privateKey.getPublicKeyPacket().getAlgorithm(), digest)); signatureGenerator.init(PGPSignature.CANONICAL_TEXT_DOCUMENT, privateKey); ArmoredOutputStream armoredOutput = new ArmoredOutputStream(output); LineIterator iterator = new LineIterator(new InputStreamReader(input)); while (iterator.hasNext()) { String line = iterator.nextLine(); // 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"); signatureGenerator.update(data); if (iterator.hasNext()) { signatureGenerator.update(EOL); } } PGPSignature signature = signatureGenerator.generate(); signature.encode(new BCPGOutputStream(armoredOutput)); armoredOutput.close(); }
public final static PGPKeyRingGenerator generateKeyRingGenerator(String id, char[] pass, int s2kcount, KeyGenPane.BackgroundTask bgt) throws Exception { // This object generates individual key-pairs. RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); // Boilerplate RSA parameters, no need to change anything // except for the RSA key-size (2048). You can use whatever key-size // makes sense for you -- 4096, etc. kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 2048, 12)); bgt.setProgressPub(10); // First create the master (signing) key with the generator. PGPKeyPair rsakp_sign = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpg.generateKeyPair(), new Date()); // Then an encryption subkey. PGPKeyPair rsakp_enc = new BcPGPKeyPair(PGPPublicKey.RSA_ENCRYPT, kpg.generateKeyPair(), new Date()); bgt.setProgressPub(50); // Add a self-signature on the id PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator(); bgt.setProgressPub(55); // Add signed metadata on the signature. // 1) Declare its purpose signhashgen.setKeyFlags(false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER); bgt.setProgressPub(60); // 2) Set preferences for secondary crypto algorithms to use when // sending messages to this key. signhashgen.setPreferredSymmetricAlgorithms(false, new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 }); signhashgen.setPreferredHashAlgorithms(false, new int[] { HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA224, }); // 3) Request senders add additional checksums to the message (useful // when verifying unsigned messages.) signhashgen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); // Create a signature on the encryption subkey. PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator(); // Add metadata to declare its purpose enchashgen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); // Objects used to encrypt the secret key. PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPDigestCalculator sha256Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA256); bgt.setProgressPub(70); // bcpg 1.48 exposes this API that includes s2kcount. Earlier versions // use a default of 0x60. PBESecretKeyEncryptor pske = (new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha256Calc, s2kcount)).build(pass); // Finally, create the keyring itself. The constructor takes parameters // that allow it to generate the self signature. PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, id, sha1Calc, signhashgen.generate(), null, new BcPGPContentSignerBuilder(rsakp_sign.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), pske); bgt.setProgressPub(80); // Add our encryption subkey, together with its signature. keyRingGen.addSubKey(rsakp_enc, enchashgen.generate(), null); bgt.setProgressPub(90); return keyRingGen; }
static PGPKeyRingGenerator generateKeyRingGenerator(String userId, int numBits, char[] passphrase) throws Exception { RSAKeyPairGenerator keyPairGenerator = new RSAKeyPairGenerator(); keyPairGenerator.init( new RSAKeyGenerationParameters( BigInteger.valueOf(0x10001), new SecureRandom(), numBits, 12 ) ); PGPKeyPair rsaKeyPairSign = new BcPGPKeyPair( PGPPublicKey.RSA_SIGN, keyPairGenerator.generateKeyPair(), new Date() ); PGPKeyPair rsaKeyPairEncrypt = new BcPGPKeyPair( PGPPublicKey.RSA_ENCRYPT, keyPairGenerator.generateKeyPair(), new Date() ); PGPSignatureSubpacketGenerator signHashGenerator = new PGPSignatureSubpacketGenerator(); signHashGenerator.setKeyFlags(false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER); signHashGenerator.setPreferredSymmetricAlgorithms( false, new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 } ); signHashGenerator.setPreferredHashAlgorithms( false, new int[] { HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, // Not recommended HashAlgorithmTags.SHA224, // Not recommended } ); signHashGenerator.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); PGPSignatureSubpacketGenerator encryptHashGenerator = new PGPSignatureSubpacketGenerator(); encryptHashGenerator.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE); PGPDigestCalculator sha1DigestCalculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPDigestCalculator sha512DigestCalculator = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA512); PBESecretKeyEncryptor secretKeyEncryptor = ( new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha512DigestCalculator) ) .build(passphrase); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator( PGPSignature.NO_CERTIFICATION, rsaKeyPairSign, userId, sha1DigestCalculator, signHashGenerator.generate(), null, new BcPGPContentSignerBuilder(rsaKeyPairSign.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA512), secretKeyEncryptor ); keyRingGen.addSubKey(rsaKeyPairEncrypt, encryptHashGenerator.generate(), null); return keyRingGen; }
/** * Builds a PGPContentSignerBuilder for the specified algorithms. */ protected PGPContentSignerBuilder buildSignerBuilder( int keyAlgorithm, int hashAlgorithm) { return new BcPGPContentSignerBuilder(keyAlgorithm, hashAlgorithm); }
private void embeddedJpegTest() throws Exception { PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator()); PGPSecretKeyRing pgpSec = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator()); PGPPublicKey pubKey = pgpPub.getPublicKey(); PGPUserAttributeSubpacketVectorGenerator vGen = new PGPUserAttributeSubpacketVectorGenerator(); vGen.setImageAttribute(ImageAttribute.JPEG, jpegImage); PGPUserAttributeSubpacketVector uVec = vGen.generate(); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.POSITIVE_CERTIFICATION, pgpSec.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass))); PGPSignature sig = sGen.generateCertification(uVec, pubKey); PGPPublicKey nKey = PGPPublicKey.addCertification(pubKey, uVec, sig); Iterator it = nKey.getUserAttributes(); int count = 0; while (it.hasNext()) { PGPUserAttributeSubpacketVector attributes = (PGPUserAttributeSubpacketVector)it.next(); Iterator sigs = nKey.getSignaturesForUserAttribute(attributes); int sigCount = 0; while (sigs.hasNext()) { PGPSignature s = (PGPSignature)sigs.next(); s.init(new BcPGPContentVerifierBuilderProvider(), pubKey); if (!s.verifyCertification(attributes, pubKey)) { fail("added signature failed verification"); } sigCount++; } if (sigCount != 1) { fail("Failed added user attributes signature check"); } count++; } if (count != 1) { fail("didn't find added user attributes"); } nKey = PGPPublicKey.removeCertification(nKey, uVec); count = 0; for (it = nKey.getUserAttributes(); it.hasNext();) { count++; } if (count != 0) { fail("found attributes where none expected"); } }
public void generateTest() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", null, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
public void generateSha1Test() throws Exception { char[] passPhrase = "hello".toCharArray(); DSAParametersGenerator dsaPGen = new DSAParametersGenerator(); dsaPGen.init(512, 10, new SecureRandom()); DSAKeyPairGenerator dsaKpg = new DSAKeyPairGenerator(); dsaKpg.init(new DSAKeyGenerationParameters(new SecureRandom(), dsaPGen.generateParameters())); // // this takes a while as the key generator has to generate some DSA params // before it generates the key. // AsymmetricCipherKeyPair dsaKp = dsaKpg.generateKeyPair(); ElGamalKeyPairGenerator elgKpg = new ElGamalKeyPairGenerator(); BigInteger g = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16); BigInteger p = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16); ElGamalParameters elParams = new ElGamalParameters(p, g); elgKpg.init(new ElGamalKeyGenerationParameters(new SecureRandom(), elParams)); // // this is quicker because we are using pregenerated parameters. // AsymmetricCipherKeyPair elgKp = elgKpg.generateKeyPair(); PGPKeyPair dsaKeyPair = new BcPGPKeyPair(PGPPublicKey.DSA, dsaKp, new Date()); PGPKeyPair elgKeyPair = new BcPGPKeyPair(PGPPublicKey.ELGAMAL_ENCRYPT, elgKp, new Date()); PGPDigestCalculator chkSumCalc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, dsaKeyPair, "test", chkSumCalc, null, null, new BcPGPContentSignerBuilder(PGPPublicKey.DSA, HashAlgorithmTags.SHA1), new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256).build(passPhrase)); keyRingGen.addSubKey(elgKeyPair); PGPSecretKeyRing keyRing = keyRingGen.generateSecretKeyRing(); keyRing.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)); PGPPublicKeyRing pubRing = keyRingGen.generatePublicKeyRing(); PGPPublicKey vKey = null; PGPPublicKey sKey = null; Iterator it = pubRing.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pk = (PGPPublicKey)it.next(); if (pk.isMasterKey()) { vKey = pk; } else { sKey = pk; } } Iterator sIt = sKey.getSignatures(); while (sIt.hasNext()) { PGPSignature sig = (PGPSignature)sIt.next(); if (sig.getKeyID() == vKey.getKeyID() && sig.getSignatureType() == PGPSignature.SUBKEY_BINDING) { sig.init(new BcPGPContentVerifierBuilderProvider(), vKey); if (!sig.verifyCertification(vKey, sKey)) { fail("failed to verify sub-key signature."); } } } }
/** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); PGPObjectFactory pgpFact = new BcPGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } }
private static PGPKeyRingGenerator generateKeyRingGenerator( String id, char[] pass, int s2kcount, int keySize, KeyPair keyPair ) throws PGPException { // This object generates individual key-pairs. RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); // Boilerplate RSA parameters, no need to change anything // except for the RSA key-size (2048). You can use whatever // key-size makes sense for you -- 4096, etc. kpg.init( new RSAKeyGenerationParameters( BigInteger.valueOf( 0x10001 ), new SecureRandom(), keySize, 12 ) ); // First create the master (signing) key with the generator. PGPKeyPair rsakp_sign = new BcPGPKeyPair( PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date() ); // Then an encryption subkey. PGPKeyPair rsakp_enc = new BcPGPKeyPair( PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date() ); keyPair.setPrimaryKeyId( Long.toHexString( rsakp_sign.getKeyID() ) ); keyPair.setPrimaryKeyFingerprint( BytesToHex( rsakp_sign.getPublicKey().getFingerprint() ) ); keyPair.setSubKeyId( Long.toHexString( rsakp_enc.getKeyID() ) ); keyPair.setSubKeyFingerprint( BytesToHex( rsakp_enc.getPublicKey().getFingerprint() ) ); // Add a self-signature on the id PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator(); // Add signed metadata on the signature. // 1) Declare its purpose signhashgen.setKeyFlags( false, KeyFlags.SIGN_DATA | KeyFlags.CERTIFY_OTHER ); // 2) Set preferences for secondary crypto algorithms to use // when sending messages to this key. signhashgen.setPreferredSymmetricAlgorithms( false, new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128, SymmetricKeyAlgorithmTags.CAST5, SymmetricKeyAlgorithmTags.TRIPLE_DES } ); signhashgen.setPreferredHashAlgorithms( false, new int[] { HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA224, } ); signhashgen.setPreferredCompressionAlgorithms( false, new int[] { CompressionAlgorithmTags.ZLIB, CompressionAlgorithmTags.BZIP2, CompressionAlgorithmTags.ZIP } ); // 3) Request senders add additional checksums to the // message (useful when verifying unsigned messages.) signhashgen.setFeature( false, Features.FEATURE_MODIFICATION_DETECTION ); // Create a signature on the encryption subkey. PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator(); // Add metadata to declare its purpose enchashgen.setKeyFlags( false, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE ); // Objects used to encrypt the secret key. PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get( HashAlgorithmTags.SHA1 ); // bcpg 1.48 exposes this API that includes s2kcount. Earlier // versions use a default of 0x60. PBESecretKeyEncryptor pske = ( new BcPBESecretKeyEncryptorBuilder( PGPEncryptedData.CAST5, sha1Calc, s2kcount ) ).build( pass ); // Finally, create the keyring itself. The constructor // takes parameters that allow it to generate the self // signature. PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator( PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, id, sha1Calc, signhashgen.generate(), null, new BcPGPContentSignerBuilder( rsakp_sign.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1 ), pske ); // Add our encryption subkey, together with its signature. keyRingGen.addSubKey( rsakp_enc, enchashgen.generate(), null ); return keyRingGen; }
public String encrypt(String message, boolean sign) throws PGPEncryptionException, PGPKeyNotFoundException { try { PGPSecretKey secretKey = ourKey.getSecretKey(); PGPPrivateKey privateKey = ourKey.getPrivateKey(); byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8); PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator(); PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor); encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey.getEncryptionKey())); PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB); PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder( secretKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA256 ); PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder); signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, (String) secretKey.getPublicKey().getUserIDs().next()); signatureGenerator.setHashedSubpackets(spGen.generate()); if (sign) { signatureGenerator.update(messageBytes); } ByteArrayOutputStream bOut = new ByteArrayOutputStream(); Hashtable<String, String> headers = new Hashtable<>(); headers.put("Version", "QPG"); ArmoredOutputStream armoredOut = new ArmoredOutputStream(bOut, headers); OutputStream encryptedOut = encryptedDataGenerator.open(armoredOut, new byte[BUFFER_SIZE]); OutputStream compressedOut = compressedDataGenerator.open(encryptedOut); if (sign) { signatureGenerator.generateOnePassVersion(false).encode(compressedOut); } OutputStream literalOut = literalDataGenerator.open( compressedOut, PGPLiteralData.UTF8, PGPLiteralData.CONSOLE, messageBytes.length, new Date() ); literalOut.write(messageBytes); literalDataGenerator.close(); if (sign) { signatureGenerator.generate().encode(compressedOut); } compressedDataGenerator.close(); encryptedDataGenerator.close(); armoredOut.close(); return new String(bOut.toByteArray(), StandardCharsets.UTF_8); } catch (PGPException | RuntimeException | IOException e) { throw new PGPEncryptionException("Error encrypting message", e); } }
@Test public void testSignVerify_OnePass() throws Exception { // Load the keys. PGPPublicKeyRing publicKeyRing = new BcPGPPublicKeyRing(PUBLIC_KEY); PGPSecretKeyRing privateKeyRing = new BcPGPSecretKeyRing(PRIVATE_KEY); PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPPrivateKey privateKey = extractPrivateKey(privateKeyRing.getSecretKey()); // Sign the data and write signature data to "signatureFile". PGPSignatureGenerator signer = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(RSA_GENERAL, SHA256)); signer.init(PGPSignature.BINARY_DOCUMENT, privateKey); addUserInfoToSignature(publicKey, signer); ByteArrayOutputStream output = new ByteArrayOutputStream(); signer.generateOnePassVersion(false).encode(output); signer.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); signer.generate().encode(output); byte[] signatureFileData = output.toByteArray(); logger.info(".sig file data: " + dumpHex(signatureFileData)); // Load algorithm information and signature data from "signatureFileData". PGPSignature sig; PGPOnePassSignature onePass; try (ByteArrayInputStream input = new ByteArrayInputStream(signatureFileData)) { PGPObjectFactory pgpFact = new BcPGPObjectFactory(input); PGPOnePassSignatureList onePassList = (PGPOnePassSignatureList) pgpFact.nextObject(); PGPSignatureList sigList = (PGPSignatureList) pgpFact.nextObject(); assertThat(onePassList.size()).isEqualTo(1); assertThat(sigList.size()).isEqualTo(1); onePass = onePassList.get(0); sig = sigList.get(0); } // Use "onePass" and "sig" to verify "publicKey" signed the text. onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey); onePass.update(FALL_OF_HYPERION_A_DREAM.getBytes(UTF_8)); assertThat(onePass.verify(sig)).isTrue(); // Verify that they DIDN'T sign the text "hello monster". onePass.init(new BcPGPContentVerifierBuilderProvider(), publicKey); onePass.update("hello monster".getBytes(UTF_8)); assertThat(onePass.verify(sig)).isFalse(); }
@Override public void sign ( final InputStream in, final OutputStream out, final boolean inline ) throws Exception { final int digest = HashAlgorithmTags.SHA1; final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator ( new BcPGPContentSignerBuilder ( this.privateKey.getPublicKeyPacket ().getAlgorithm (), digest ) ); if ( inline ) { signatureGenerator.init ( PGPSignature.CANONICAL_TEXT_DOCUMENT, this.privateKey ); } else { signatureGenerator.init ( PGPSignature.BINARY_DOCUMENT, this.privateKey ); } final ArmoredOutputStream armoredOutput = new ArmoredOutputStream ( out ); armoredOutput.setHeader ( "Version", VersionInformation.VERSIONED_PRODUCT ); if ( inline ) { armoredOutput.beginClearText ( digest ); final LineNumberReader lnr = new LineNumberReader ( new InputStreamReader ( in, StandardCharsets.UTF_8 ) ); String line; while ( ( line = lnr.readLine () ) != null ) { if ( lnr.getLineNumber () > 1 ) { signatureGenerator.update ( NL_DATA ); } final byte[] data = trimTrailing ( line ).getBytes ( StandardCharsets.UTF_8 ); if ( inline ) { armoredOutput.write ( data ); armoredOutput.write ( NL_DATA ); } signatureGenerator.update ( data ); } armoredOutput.endClearText (); } else { final byte[] buffer = new byte[4096]; int rc; while ( ( rc = in.read ( buffer ) ) >= 0 ) { signatureGenerator.update ( buffer, 0, rc ); } } final PGPSignature signature = signatureGenerator.generate (); signature.encode ( new BCPGOutputStream ( armoredOutput ) ); armoredOutput.close (); }
private PushCertificate newSignedCert(String nonce, TestKey signingKey, Date now) throws Exception { PushCertificateIdent ident = new PushCertificateIdent(signingKey.getFirstUserId(), System.currentTimeMillis(), -7 * 60); String payload = "certificate version 0.1\n" + "pusher " + ident.getRaw() + "\n" + "pushee test://localhost/repo.git\n" + "nonce " + nonce + "\n" + "\n" + "0000000000000000000000000000000000000000" + " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" + " refs/heads/master\n"; PGPSignatureGenerator gen = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(signingKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1)); if (now != null) { PGPSignatureSubpacketGenerator subGen = new PGPSignatureSubpacketGenerator(); subGen.setSignatureCreationTime(false, now); gen.setHashedSubpackets(subGen.generate()); } gen.init(PGPSignature.BINARY_DOCUMENT, signingKey.getPrivateKey()); gen.update(payload.getBytes(UTF_8)); PGPSignature sig = gen.generate(); ByteArrayOutputStream bout = new ByteArrayOutputStream(); try (BCPGOutputStream out = new BCPGOutputStream(new ArmoredOutputStream(bout))) { sig.encode(out); } String cert = payload + new String(bout.toByteArray(), UTF_8); Reader reader = new InputStreamReader(new ByteArrayInputStream(cert.getBytes(UTF_8))); PushCertificateParser parser = new PushCertificateParser(repo, signedPushConfig); return parser.parse(reader); }
@Override public void certify(final CertifyPgpKeyParam certifyPgpKeyParam) { try { assertNotNull(certifyPgpKeyParam, "certifyPgpKeyParam"); PgpKey pgpKey = assertNotNull(certifyPgpKeyParam.getPgpKey(), "certifyPgpKeyParam.pgpKey"); PgpKey signPgpKey = assertNotNull(certifyPgpKeyParam.getSignPgpKey(), "certifyPgpKeyParam.signPgpKey"); final PgpSignatureType certificationLevel = assertNotNull(certifyPgpKeyParam.getCertificationLevel(), "certifyPgpKeyParam.certificationLevel"); final HashAlgorithm hashAlgorithm = assertNotNull(certifyPgpKeyParam.getHashAlgorithm(), "certifyPgpKeyParam.hashAlgorithm"); if (pgpKey.getMasterKey() != null) pgpKey = pgpKey.getMasterKey(); if (signPgpKey.getMasterKey() != null) signPgpKey = signPgpKey.getMasterKey(); final BcPgpKey bcPgpKey = getBcPgpKeyOrFail(pgpKey); final BcPgpKey bcSignPgpKey = getBcPgpKeyOrFail(signPgpKey); if (! PgpSignatureType.CERTIFICATIONS.contains(certificationLevel)) throw new IllegalArgumentException("certifyPgpKeyParam.certificationLevel is not contained in PgpSignatureType.CERTIFICATIONS."); final PgpAuthenticationCallback callback = getPgpAuthenticationCallbackOrFail(); final char[] signPassphrase = callback.getPassphrase(signPgpKey); PGPPublicKeyRing publicKeyRing = bcPgpKey.getPublicKeyRing(); final PGPSecretKey signSecretKey = bcSignPgpKey.getSecretKey(); if (signSecretKey == null) throw new IllegalArgumentException("signPgpKey does not have a secret key assigned!"); final PGPPrivateKey signPrivKey = signSecretKey.extractPrivateKey( new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(signPassphrase)); final PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(signSecretKey.getPublicKey().getAlgorithm(), hashAlgorithm.getHashAlgorithmTag())); signatureGenerator.init(signatureTypeFromEnum(certificationLevel), signPrivKey); if (pgpKey.getUserIds().isEmpty()) throw new IllegalArgumentException("certifyPgpKeyParam.pgpKey.userIds is empty!"); for (final String userId : pgpKey.getUserIds()) { final PGPPublicKey publicKey = publicKeyRing.getPublicKey(); PGPSignature signature = signatureGenerator.generateCertification(userId, publicKey); PGPPublicKey newKey = PGPPublicKey.addCertification(publicKey, userId, signature); PGPPublicKeyRing newPublicKeyRing = PGPPublicKeyRing.removePublicKey(publicKeyRing, publicKey); newPublicKeyRing = PGPPublicKeyRing.insertPublicKey(newPublicKeyRing, newKey); publicKeyRing = newPublicKeyRing; } final ImportKeysResult importKeysResult = new ImportKeysResult(); final boolean modified = importPublicKeyRing(importKeysResult, publicKeyRing); if (modified) // make sure the localRevision is incremented, even if the timestamp does not change (e.g. because the time resolution of the file system is too low). incLocalRevision(); } catch (IOException | PGPException e) { throw new RuntimeException(e); } }
/** * Encrypt, sign and write input stream data to output stream. * Input and output stream are closed. */ private static void encryptAndSign( InputStream plainInput, OutputStream encryptedOutput, PersonalKey myKey, List<PGPUtils.PGPCoderKey> receiverKeys) throws IOException, PGPException { // setup data encryptor & generator BcPGPDataEncryptorBuilder encryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.AES_192); encryptor.setWithIntegrityPacket(true); encryptor.setSecureRandom(new SecureRandom()); // add public key recipients PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator(encryptor); receiverKeys.forEach(key -> encGen.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(key.encryptKey))); OutputStream encryptedOut = encGen.open(encryptedOutput, new byte[BUFFER_SIZE]); // setup compressed data generator PGPCompressedDataGenerator compGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); OutputStream compressedOut = compGen.open(encryptedOut, new byte[BUFFER_SIZE]); // setup signature generator int algo = myKey.getSigningAlgorithm(); PGPSignatureGenerator sigGen = new PGPSignatureGenerator( new BcPGPContentSignerBuilder(algo, HashAlgorithmTags.SHA256)); sigGen.init(PGPSignature.BINARY_DOCUMENT, myKey.getPrivateSigningKey()); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, myKey.getUserId()); sigGen.setUnhashedSubpackets(spGen.generate()); sigGen.generateOnePassVersion(false).encode(compressedOut); // Initialize literal data generator PGPLiteralDataGenerator literalGen = new PGPLiteralDataGenerator(); OutputStream literalOut = literalGen.open( compressedOut, PGPLiteralData.BINARY, "", new Date(), new byte[BUFFER_SIZE]); // read the "in" stream, compress, encrypt and write to the "out" stream // this must be done if clear data is bigger than the buffer size // but there are other ways to optimize... byte[] buf = new byte[BUFFER_SIZE]; int len; while ((len = plainInput.read(buf)) > 0) { literalOut.write(buf, 0, len); sigGen.update(buf, 0, len); } literalGen.close(); // generate the signature, compress, encrypt and write to the "out" stream sigGen.generate().encode(compressedOut); compGen.close(); encGen.close(); }
/** * Generated signature test * * @param sKey * @param pgpPrivKey */ public void generateTest( PGPSecretKeyRing sKey, PGPPublicKey pgpPubKey, PGPPrivateKey pgpPrivKey) throws Exception { String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.DSA, HashAlgorithmTags.SHA1)); sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); Iterator it = sKey.getSecretKey().getPublicKey().getUserIDs(); String primaryUserID = (String)it.next(); spGen.setSignerUserID(true, primaryUserID); sGen.setHashedSubpackets(spGen.generate()); sGen.generateOnePassVersion(false).encode(bOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000); OutputStream lOut = lGen.open( new UncloseableOutputStream(bOut), PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, testDate); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte)ch); } lGen.close(); sGen.generate().encode(bOut); PGPObjectFactory pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject(); if (!p2.getModificationTime().equals(testDate)) { fail("Modification time not preserved"); } InputStream dIn = p2.getInputStream(); ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPubKey); while ((ch = dIn.read()) >= 0) { ops.update((byte)ch); } PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { fail("Failed generated signature check"); } }