PublicKey pubKey = null;
//
// Read the public key
//
PGPPublicKeyRing pgpPub = new PGPPublicKeyRing(testPubKey, new BcKeyFingerprintCalculator());
pubKey = pgpPub.getPublicKey().getKey("BC");
Iterator it = pgpPub.getPublicKey().getUserIDs();
String uid = (String)it.next();
it = pgpPub.getPublicKey().getSignaturesForID(uid);
PGPSignature sig = (PGPSignature)it.next();
sig.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey());
if (!sig.verifyCertification(uid, pgpPub.getPublicKey()))
{
fail("failed to verify certification");
}
//
// write a public key
//
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
BCPGOutputStream pOut = new BCPGOutputStream(bOut);
pgpPub.encode(pOut);
if (!areEqual(bOut.toByteArray(), testPubKey))
{
fail("public key rewrite failed");
}
//
// Read the public key
//
PGPPublicKeyRing pgpPubV3 = new PGPPublicKeyRing(testPubKeyV3, new BcKeyFingerprintCalculator());
PublicKey pubKeyV3 = pgpPub.getPublicKey().getKey("BC");
//
// write a V3 public key
//
bOut = new ByteArrayOutputStream();
pOut = new BCPGOutputStream(bOut);
pgpPubV3.encode(pOut);
//
// Read a v3 private key
//
char[] passP = "FIXCITY_QA".toCharArray();
if (!noIDEA())
{
PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKeyV3, new BcKeyFingerprintCalculator());
PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passP));
//
// write a v3 private key
//
bOut = new ByteArrayOutputStream();
pOut = new BCPGOutputStream(bOut);
pgpPriv.encode(pOut);
if (!areEqual(bOut.toByteArray(), testPrivKeyV3))
{
fail("private key V3 rewrite failed");
}
}
//
// Read the private key
//
PGPSecretKeyRing pgpPriv = new PGPSecretKeyRing(testPrivKey, new BcKeyFingerprintCalculator());
PGPPrivateKey pgpPrivKey = pgpPriv.getSecretKey().extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
//
// write a private key
//
bOut = new ByteArrayOutputStream();
pOut = new BCPGOutputStream(bOut);
pgpPriv.encode(pOut);
if (!areEqual(bOut.toByteArray(), testPrivKey))
{
fail("private key rewrite failed");
}
//
// test encryption
//
Cipher c = Cipher.getInstance("RSA", "BC");
c.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] in = "hello world".getBytes();
byte[] out = c.doFinal(in);
c.init(Cipher.DECRYPT_MODE, pgpPrivKey.getKey());
out = c.doFinal(out);
if (!areEqual(in, out))
{
fail("decryption failed.");
}
//
// test signature message
//
PGPObjectFactory pgpFact = new PGPObjectFactory(sig1, new BcKeyFingerprintCalculator());
PGPCompressedData c1 = (PGPCompressedData)pgpFact.nextObject();
pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator());
PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
PGPOnePassSignature ops = p1.get(0);
PGPLiteralData p2 = (PGPLiteralData)pgpFact.nextObject();
InputStream dIn = p2.getInputStream();
int ch;
ops.init(new BcPGPContentVerifierBuilderProvider(), pgpPub.getPublicKey(ops.getKeyID()));
while ((ch = dIn.read()) >= 0)
{
ops.update((byte)ch);
}
PGPSignatureList p3 = (PGPSignatureList)pgpFact.nextObject();
if (!ops.verify(p3.get(0)))
{
fail("Failed signature check");
}
//
// encrypted message - read subkey
//
pgpPriv = new PGPSecretKeyRing(subKey, new BcKeyFingerprintCalculator());
//
// 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(enc1, new BcKeyFingerprintCalculator());
PGPEncryptedDataList encList = (PGPEncryptedDataList)pgpF.nextObject();
PGPPublicKeyEncryptedData encP = (PGPPublicKeyEncryptedData)encList.get(0);
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
InputStream clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
pgpFact = new PGPObjectFactory(clear, new BcKeyFingerprintCalculator());
c1 = (PGPCompressedData)pgpFact.nextObject();
pgpFact = new PGPObjectFactory(c1.getDataStream(), new BcKeyFingerprintCalculator());
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 (!areEqual(bOut.toByteArray(), text))
{
fail("wrong plain text in decrypted packet");
}
//
// encrypt - short message
//
byte[] shortText = { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' };
ByteArrayOutputStream cbOut = new ByteArrayOutputStream();
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom()));
PGPPublicKey puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey();
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
OutputStream cOut = cPk.open(new UncloseableOutputStream(cbOut), shortText.length);
cOut.write(shortText);
cOut.close();
pgpF = new PGPObjectFactory(cbOut.toByteArray(), new BcKeyFingerprintCalculator());
encList = (PGPEncryptedDataList)pgpF.nextObject();
encP = (PGPPublicKeyEncryptedData)encList.get(0);
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
PublicKeyDataDecryptorFactory dataDecryptorFactory = new BcPublicKeyDataDecryptorFactory(pgpPrivKey);
if (encP.getSymmetricAlgorithm(dataDecryptorFactory) != SymmetricKeyAlgorithmTags.CAST5)
{
fail("symmetric algorithm mismatch");
}
clear = encP.getDataStream(dataDecryptorFactory);
bOut.reset();
while ((ch = clear.read()) >= 0)
{
bOut.write(ch);
}
out = bOut.toByteArray();
if (!areEqual(out, shortText))
{
fail("wrong plain text in generated short text packet");
}
//
// encrypt
//
cbOut = new ByteArrayOutputStream();
cPk = new PGPEncryptedDataGenerator(new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).setSecureRandom(new SecureRandom()));
puK = pgpPriv.getSecretKey(encP.getKeyID()).getPublicKey();
cPk.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(puK));
cOut = cPk.open(new UncloseableOutputStream(cbOut), text.length);
cOut.write(text);
cOut.close();
pgpF = new PGPObjectFactory(cbOut.toByteArray());
encList = (PGPEncryptedDataList)pgpF.nextObject();
encP = (PGPPublicKeyEncryptedData)encList.get(0);
pgpPrivKey = pgpPriv.getSecretKey(encP.getKeyID()).extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass));
clear = encP.getDataStream(new BcPublicKeyDataDecryptorFactory(pgpPrivKey));
bOut.reset();
while ((ch = clear.read()) >= 0)
{
bOut.write(ch);
}
out = bOut.toByteArray();
if (!areEqual(out, text))
{
fail("wrong plain text in generated packet");
}
//
// read public key with sub key.
//
pgpF = new PGPObjectFactory(subPubKey, new BcKeyFingerprintCalculator());
Object o;
while ((o = pgpFact.nextObject()) != null)
{
// System.out.println(o);
}
//
// key pair generation - CAST5 encryption
//
char[] passPhrase = "hello".toCharArray();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
kpg.initialize(1024);
KeyPair kp = kpg.generateKeyPair();
PGPSecretKey secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", null, null, new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1).setProvider("BC"), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.CAST5).build(passPhrase));
PGPPublicKey key = secretKey.getPublicKey();
it = key.getUserIDs();
uid = (String)it.next();
it = key.getSignaturesForID(uid);
sig = (PGPSignature)it.next();
sig.init(new BcPGPContentVerifierBuilderProvider(), key);
if (!sig.verifyCertification(uid, key))
{
fail("failed to verify certification");
}
pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase));
key = PGPPublicKey.removeCertification(key, uid, sig);
if (key == null)
{
fail("failed certification removal");
}
byte[] keyEnc = key.getEncoded();
key = PGPPublicKey.addCertification(key, uid, sig);
keyEnc = key.getEncoded();
PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1));
sGen.init(PGPSignature.KEY_REVOCATION, secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase)));
sig = sGen.generateCertification(key);
key = PGPPublicKey.addCertification(key, sig);
keyEnc = key.getEncoded();
PGPPublicKeyRing tmpRing = new PGPPublicKeyRing(keyEnc, new BcKeyFingerprintCalculator());
key = tmpRing.getPublicKey();
Iterator sgIt = key.getSignaturesOfType(PGPSignature.KEY_REVOCATION);
sig = (PGPSignature)sgIt.next();
sig.init(new BcPGPContentVerifierBuilderProvider(), key);
if (!sig.verifyCertification(key))
{
fail("failed to verify revocation certification");
}
//
// use of PGPKeyPair
//
PGPKeyPair pgpKp = new PGPKeyPair(PGPPublicKey.RSA_GENERAL , kp.getPublic(), kp.getPrivate(), new Date());
PGPPublicKey k1 = pgpKp.getPublicKey();
PGPPrivateKey k2 = pgpKp.getPrivateKey();
k1.getEncoded();
mixedTest(k2, k1);
//
// key pair generation - AES_256 encryption.
//
kp = kpg.generateKeyPair();
secretKey = new PGPSecretKey(PGPSignature.DEFAULT_CERTIFICATION, PublicKeyAlgorithmTags.RSA_GENERAL, kp.getPublic(), kp.getPrivate(), new Date(), "fred", null, null, new JcaPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1).setProvider("BC"), new BcPBESecretKeyEncryptorBuilder(SymmetricKeyAlgorithmTags.AES_256).build(passPhrase));
secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase));
secretKey.encode(new ByteArrayOutputStream());
//
// secret key password changing.
//
String newPass = "newPass";
secretKey = PGPSecretKey.copyWithNewPassword(secretKey, new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(passPhrase), new BcPBESecretKeyEncryptorBuilder(secretKey.getKeyEncryptionAlgorithm()).build(newPass.toCharArray()));
secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray()));
secretKey.encode(new ByteArrayOutputStream());
key = secretKey.getPublicKey();
key.encode(new ByteArrayOutputStream());
it = key.getUserIDs();
uid = (String)it.next();
it = key.getSignaturesForID(uid);
sig = (PGPSignature)it.next();
sig.init(new BcPGPContentVerifierBuilderProvider(), key);
if (!sig.verifyCertification(uid, key))
{
fail("failed to verify certification");
}
pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(newPass.toCharArray()));
//
// signature generation
//
String data = "hello world!";
bOut = new ByteArrayOutputStream();
ByteArrayInputStream testIn = new ByteArrayInputStream(data.getBytes());
sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(PublicKeyAlgorithmTags.RSA_GENERAL, HashAlgorithmTags.SHA1));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);
BCPGOutputStream bcOut = new BCPGOutputStream(
cGen.open(new UncloseableOutputStream(bOut)));
sGen.generateOnePassVersion(false).encode(bcOut);
PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator();
Date testDate = new Date((System.currentTimeMillis() / 1000) * 1000);
OutputStream lOut = lGen.open(
new UncloseableOutputStream(bcOut),
PGPLiteralData.BINARY,
"_CONSOLE",
data.getBytes().length,
testDate);
while ((ch = testIn.read()) >= 0)
{
lOut.write(ch);
sGen.update((byte)ch);
}
lOut.close();
sGen.generate().encode(bcOut);
bcOut.close();
//
// verify generated signature
//
pgpFact = new PGPObjectFactory(bOut.toByteArray());
c1 = (PGPCompressedData)pgpFact.nextObject();
pgpFact = new PGPObjectFactory(c1.getDataStream());
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
ops = p1.get(0);
p2 = (PGPLiteralData)pgpFact.nextObject();
if (!p2.getModificationTime().equals(testDate))
{
fail("Modification time not preserved: " + p2.getModificationTime() + " " + testDate);
}
dIn = p2.getInputStream();
ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey());
while ((ch = dIn.read()) >= 0)
{
ops.update((byte)ch);
}
p3 = (PGPSignatureList)pgpFact.nextObject();
if (!ops.verify(p3.get(0)))
{
fail("Failed generated signature check");
}
//
// signature generation - version 3
//
bOut = new ByteArrayOutputStream();
testIn = new ByteArrayInputStream(data.getBytes());
PGPV3SignatureGenerator sGenV3 = new PGPV3SignatureGenerator(new BcPGPContentSignerBuilder(PGPPublicKey.RSA_GENERAL, PGPUtil.SHA1));
sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
cGen = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);
bcOut = new BCPGOutputStream(cGen.open(bOut));
sGen.generateOnePassVersion(false).encode(bcOut);
lGen = new PGPLiteralDataGenerator();
lOut = lGen.open(
new UncloseableOutputStream(bcOut),
PGPLiteralData.BINARY,
"_CONSOLE",
data.getBytes().length,
testDate);
while ((ch = testIn.read()) >= 0)
{
lOut.write(ch);
sGen.update((byte)ch);
}
lOut.close();
sGen.generate().encode(bcOut);
bcOut.close();
//
// verify generated signature
//
pgpFact = new PGPObjectFactory(bOut.toByteArray());
c1 = (PGPCompressedData)pgpFact.nextObject();
pgpFact = new PGPObjectFactory(c1.getDataStream());
p1 = (PGPOnePassSignatureList)pgpFact.nextObject();
ops = p1.get(0);
p2 = (PGPLiteralData)pgpFact.nextObject();
if (!p2.getModificationTime().equals(testDate))
{
fail("Modification time not preserved");
}
dIn = p2.getInputStream();
ops.init(new BcPGPContentVerifierBuilderProvider(), secretKey.getPublicKey());
while ((ch = dIn.read()) >= 0)
{
ops.update((byte)ch);
}
p3 = (PGPSignatureList)pgpFact.nextObject();
if (!ops.verify(p3.get(0)))
{
fail("Failed v3 generated signature check");
}
//
// extract PGP 8 private key
//
pgpPriv = new PGPSecretKeyRing(pgp8Key, new BcKeyFingerprintCalculator());
secretKey = pgpPriv.getSecretKey();
pgpPrivKey = secretKey.extractPrivateKey(new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pgp8Pass));