Cipher createStreamCipher(int encAlgorithm, boolean withIntegrityPacket) throws PGPException { String mode = (withIntegrityPacket) ? "CFB" : "OpenPGPCFB"; String cName = PGPUtil.getSymmetricCipherName(encAlgorithm) + "/" + mode + "/NoPadding"; return createCipher(cName); }
PGPDataDecryptor createDataDecryptor(boolean withIntegrityPacket, int encAlgorithm, byte[] key) throws PGPException { try { SecretKey secretKey = new SecretKeySpec(key, PGPUtil.getSymmetricCipherName(encAlgorithm)); final Cipher c = createStreamCipher(encAlgorithm, withIntegrityPacket); if (withIntegrityPacket) { byte[] iv = new byte[c.getBlockSize()]; c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); } else { c.init(Cipher.DECRYPT_MODE, secretKey); } return new PGPDataDecryptor() { public InputStream getInputStream(InputStream in) { return new CipherInputStream(in, c); } public int getBlockSize() { return c.getBlockSize(); } public PGPDigestCalculator getIntegrityCalculator() { return new SHA1PGPDigestCalculator(); } }; } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception creating cipher", e); } }
private PGPPublicKeyRingCollection readPublicKey(final String keytext) throws IOException, PGPException { PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection( PGPUtil.getDecoderStream(new ByteArrayInputStream(keytext.getBytes()))); return pgpPub; }
/** * 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); }
MessageDigest createDigest(int algorithm) throws GeneralSecurityException, PGPException { MessageDigest dig; try { dig = helper.createDigest(PGPUtil.getDigestName(algorithm)); } catch (NoSuchAlgorithmException e) { throw new PGPException("cannot find algorithm: " + e.getMessage(), e); } catch (NoSuchProviderException e) { throw new PGPException("cannot find provider: " + e.getMessage(), e); } return dig; }
@SuppressWarnings("resource") private static PGPPublicKeyRingCollection readPubRing(final File pub) { try { InputStream in = new FileInputStream(pub); try { in = PGPUtil.getDecoderStream(in); return new PGPPublicKeyRingCollection(in); } finally { in.close(); } } catch (IOException e) { throw new ProvisionException("Cannot read " + pub, e); } catch (PGPException e) { throw new ProvisionException("Cannot read " + pub, e); } }
static PGPPublicKey readPublicKey(String keyringPath) throws Exception { InputStream input = new ByteArrayInputStream(getKeyRing(keyringPath)); PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input)); @SuppressWarnings("rawtypes") Iterator keyRingIter = pgpPub.getKeyRings(); while (keyRingIter.hasNext()) { PGPPublicKeyRing keyRing = (PGPPublicKeyRing) keyRingIter.next(); @SuppressWarnings("rawtypes") Iterator keyIter = keyRing.getPublicKeys(); while (keyIter.hasNext()) { PGPPublicKey key = (PGPPublicKey) keyIter.next(); if (key.isEncryptionKey()) { return key; } } } throw new IllegalArgumentException("Can't find encryption key in key ring."); }
static PGPSecretKey readSecretKey() throws Exception { InputStream input = new ByteArrayInputStream(getSecKeyRing()); PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input)); @SuppressWarnings("rawtypes") Iterator keyRingIter = pgpSec.getKeyRings(); while (keyRingIter.hasNext()) { PGPSecretKeyRing keyRing = (PGPSecretKeyRing) keyRingIter.next(); @SuppressWarnings("rawtypes") Iterator keyIter = keyRing.getSecretKeys(); while (keyIter.hasNext()) { PGPSecretKey key = (PGPSecretKey) keyIter.next(); if (key.isSigningKey()) { return key; } } } throw new IllegalArgumentException("Can't find signing key in key ring."); }
/** * Returns the secret key matching the specified identifier. * * @param input the input stream containing the keyring collection * @param keyId the 4 bytes identifier of the key */ private static PGPSecretKey getSecretKey(InputStream input, String keyId) throws IOException, PGPException { PGPSecretKeyRingCollection keyrings = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(input)); Iterator rIt = keyrings.getKeyRings(); while (rIt.hasNext()) { PGPSecretKeyRing kRing = (PGPSecretKeyRing) rIt.next(); Iterator kIt = kRing.getSecretKeys(); while (kIt.hasNext()) { PGPSecretKey key = (PGPSecretKey) kIt.next(); if (key.isSigningKey() && Long.toHexString(key.getKeyID() & 0xFFFFFFFFL).equals(keyId.toLowerCase())) { return key; } } } return null; }
public Signature createSignature(int keyAlgorithm, int hashAlgorithm) throws PGPException { String encAlg; switch (keyAlgorithm) { case PublicKeyAlgorithmTags.RSA_GENERAL: case PublicKeyAlgorithmTags.RSA_SIGN: encAlg = "RSA"; break; case PublicKeyAlgorithmTags.DSA: encAlg = "DSA"; break; case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT: // in some malformed cases. case PublicKeyAlgorithmTags.ELGAMAL_GENERAL: encAlg = "ElGamal"; break; case PublicKeyAlgorithmTags.ECDSA: encAlg = "ECDSA"; break; default: throw new PGPException("unknown algorithm tag in signature:" + keyAlgorithm); } return createSignature(PGPUtil.getDigestName(hashAlgorithm) + "with" + encAlg); }
public TestResult perform() { try { String file = null; KeyFactory fact = KeyFactory.getInstance("DSA", "BC"); PGPPublicKey pubKey = null; PrivateKey privKey = null; PGPUtil.setDefaultProvider("BC"); // // Read the public key // PGPObjectFactory pgpFact = new PGPObjectFactory(testPubKeyRing); PGPPublicKeyRing pgpPub = (PGPPublicKeyRing) pgpFact.nextObject(); pubKey = pgpPub.getPublicKey(); // // Read the private key // PGPSecretKeyRing sKey = new PGPSecretKeyRing(testPrivKeyRing); PGPPrivateKey pgpPrivKey = sKey.getSecretKey().extractPrivateKey(pass, "BC"); // // signature generation // String data = "hello world!"; ByteArrayOutputStream bOut = new ByteArrayOutputStream(); ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes()); PGPSignatureGenerator sGen = new PGPSignatureGenerator(PGPPublicKey.DSA, PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(PGPCompressedData.ZIP); BCPGOutputStream bcOut = new BCPGOutputStream(cGen.open(bOut)); sGen.generateOnePassVersion(false).encode(bcOut); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); OutputStream lOut = lGen.open(bcOut, PGPLiteralData.BINARY, "_CONSOLE", data.getBytes().length, new Date()); int ch; while ((ch = testIn.read()) >= 0) { lOut.write(ch); sGen.update((byte) ch); } sGen.generate().encode(bcOut); lGen.close(); cGen.close(); // // verify generated signature // pgpFact = new PGPObjectFactory(bOut.toByteArray()); PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPOnePassSignatureList p1 = (PGPOnePassSignatureList) pgpFact.nextObject(); PGPOnePassSignature ops = p1.get(0); PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject(); InputStream dIn = p2.getInputStream(); ops.initVerify(pubKey, "BC"); while ((ch = dIn.read()) >= 0) { ops.update((byte) ch); } PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { return new SimpleTestResult(false, getName() + ": Failed generated signature check"); } // // test encryption // // // find a key sutiable for encryption // long pgpKeyID = 0; PublicKey pKey = null; Iterator it = pgpPub.getPublicKeys(); while (it.hasNext()) { PGPPublicKey pgpKey = (PGPPublicKey) it.next(); if (pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT || pgpKey.getAlgorithm() == PGPPublicKey.ELGAMAL_GENERAL) { pKey = pgpKey.getKey("BC"); pgpKeyID = pgpKey.getKeyID(); // // verify the key // } } Cipher c = Cipher.getInstance("ElGamal/None/PKCS1Padding", "BC"); c.init(Cipher.ENCRYPT_MODE, pKey); byte[] in = "hello world".getBytes(); byte[] out = c.doFinal(in); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey()); out = c.doFinal(out); if (notEqual(in, out)) { return new SimpleTestResult(false, getName() + ": decryption failed."); } // // encrypted message // byte[] text = { (byte) 'h', (byte) 'e', (byte) 'l', (byte) 'l', (byte) 'o', (byte) ' ', (byte) 'w', (byte) 'o', (byte) 'r', (byte) 'l', (byte) 'd', (byte) '!', (byte) '\n' }; PGPObjectFactory pgpF = new PGPObjectFactory(encMessage); PGPEncryptedDataList encList = (PGPEncryptedDataList) pgpF.nextObject(); PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData) encList.get(0); InputStream clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } InputStream inLd = ld.getDataStream(); while ((ch = inLd.read()) >= 0) { bOut.write(ch); } if (notEqual(bOut.toByteArray(), text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet"); } // // signed and encrypted message // pgpF = new PGPObjectFactory(signedAndEncMessage); encList = (PGPEncryptedDataList) pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData) encList.get(0); clear = encP.getDataStream(pgpPrivKey, "BC"); pgpFact = new PGPObjectFactory(clear); c1 = (PGPCompressedData) pgpFact.nextObject(); pgpFact = new PGPObjectFactory(c1.getDataStream()); p1 = (PGPOnePassSignatureList) pgpFact.nextObject(); ops = p1.get(0); ld = (PGPLiteralData) pgpFact.nextObject(); bOut = new ByteArrayOutputStream(); if (!ld.getFileName().equals("test.txt")) { throw new RuntimeException("wrong filename in packet"); } inLd = ld.getDataStream(); // // note: we use the DSA public key here. // ops.initVerify(pgpPub.getPublicKey(), "BC"); while ((ch = inLd.read()) >= 0) { ops.update((byte) ch); bOut.write(ch); } p3 = (PGPSignatureList) pgpFact.nextObject(); if (!ops.verify(p3.get(0))) { return new SimpleTestResult(false, getName() + ": Failed signature check"); } if (notEqual(bOut.toByteArray(), text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in decrypted packet"); } // // encrypt // ByteArrayOutputStream cbOut = new ByteArrayOutputStream(); PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator( SymmetricKeyAlgorithmTags.TRIPLE_DES, new SecureRandom(), "BC"); PGPPublicKey puK = sKey.getSecretKey(pgpKeyID).getPublicKey(); cPk.addMethod(puK); OutputStream cOut = cPk.open(cbOut, bOut.toByteArray().length); cOut.write(text); cOut.close(); pgpF = new PGPObjectFactory(cbOut.toByteArray()); encList = (PGPEncryptedDataList) pgpF.nextObject(); encP = (PGPPublicKeyEncryptedData) encList.get(0); pgpPrivKey = sKey.getSecretKey(pgpKeyID).extractPrivateKey(pass, "BC"); clear = encP.getDataStream(pgpPrivKey, "BC"); bOut.reset(); while ((ch = clear.read()) >= 0) { bOut.write(ch); } out = bOut.toByteArray(); if (notEqual(out, text)) { return new SimpleTestResult(false, getName() + ": wrong plain text in generated packet"); } return new SimpleTestResult(true, getName() + ": Okay"); } catch (Exception e) { e.printStackTrace(); if (e instanceof PGPException) { ((PGPException) e).getUnderlyingException().printStackTrace(); } return new SimpleTestResult(false, getName() + ": exception - " + e.toString()); } }