public void test_key(BigInteger keyId, String passphrase) throws Exception { PGPSecretKeyRingCollection secretKeyRing = loadSecretKeyCollection("secring.gpg"); PGPSecretKeyRing secretKey = secretKeyRing.getSecretKeyRing(keyId.longValue()); assertNotNull("Could not locate secret keyring with Id=" + keyId.toString(16), secretKey); PGPSecretKey key = secretKey.getSecretKey(); assertNotNull("Could not locate secret key!", key); try { PGPDigestCalculatorProvider calcProvider = new JcaPGPDigestCalculatorProviderBuilder() .setProvider(BouncyCastleProvider.PROVIDER_NAME) .build(); PBESecretKeyDecryptor decryptor = new JcePBESecretKeyDecryptorBuilder(calcProvider) .setProvider(BouncyCastleProvider.PROVIDER_NAME) .build(passphrase.toCharArray()); PGPPrivateKey privateKey = key.extractPrivateKey(decryptor); assertTrue(privateKey.getKeyID() == keyId.longValue()); } catch (PGPException e) { throw new PGPException("Password incorrect!", e); } // all fine! }
public PrivateKey getPrivateKey(PGPPrivateKey privKey) throws PGPException { PublicKeyPacket pubPk = privKey.getPublicKeyPacket(); BCPGKey privPk = privKey.getPrivateKeyDataPacket(); try { KeyFactory fact; switch (pubPk.getAlgorithm()) { case PGPPublicKey.RSA_ENCRYPT: case PGPPublicKey.RSA_GENERAL: case PGPPublicKey.RSA_SIGN: RSAPublicBCPGKey rsaPub = (RSAPublicBCPGKey) pubPk.getKey(); RSASecretBCPGKey rsaPriv = (RSASecretBCPGKey) privPk; RSAPrivateCrtKeySpec rsaPrivSpec = new RSAPrivateCrtKeySpec( rsaPriv.getModulus(), rsaPub.getPublicExponent(), rsaPriv.getPrivateExponent(), rsaPriv.getPrimeP(), rsaPriv.getPrimeQ(), rsaPriv.getPrimeExponentP(), rsaPriv.getPrimeExponentQ(), rsaPriv.getCrtCoefficient()); fact = helper.createKeyFactory("RSA"); return fact.generatePrivate(rsaPrivSpec); case PGPPublicKey.DSA: DSAPublicBCPGKey dsaPub = (DSAPublicBCPGKey) pubPk.getKey(); DSASecretBCPGKey dsaPriv = (DSASecretBCPGKey) privPk; DSAPrivateKeySpec dsaPrivSpec = new DSAPrivateKeySpec(dsaPriv.getX(), dsaPub.getP(), dsaPub.getQ(), dsaPub.getG()); fact = helper.createKeyFactory("DSA"); return fact.generatePrivate(dsaPrivSpec); case PGPPublicKey.ELGAMAL_ENCRYPT: case PGPPublicKey.ELGAMAL_GENERAL: ElGamalPublicBCPGKey elPub = (ElGamalPublicBCPGKey) pubPk.getKey(); ElGamalSecretBCPGKey elPriv = (ElGamalSecretBCPGKey) privPk; ElGamalPrivateKeySpec elSpec = new ElGamalPrivateKeySpec( elPriv.getX(), new ElGamalParameterSpec(elPub.getP(), elPub.getG())); fact = helper.createKeyFactory("ElGamal"); return fact.generatePrivate(elSpec); default: throw new PGPException("unknown public key algorithm encountered"); } } catch (PGPException e) { throw e; } catch (Exception e) { throw new PGPException("Exception constructing key", e); } }
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()); } }