我正在尝试使用 BouncyCastle 库创建签名和加密的消息,然后在命令行上针对 gpg 进行测试以确认它是否有效。然而,虽然它显示了一条看起来不错的 PGP 消息,但 gpg 在解密它时遇到了麻烦。
Java代码:
public class main {
public static void signEncryptMessage(InputStream in, OutputStream out, PGPPublicKey publicKey, PGPPrivateKey secretKey) throws Exception {
out = new ArmoredOutputStream(out);
BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(PGPEncryptedData.CAST5);
dataEncryptor.setWithIntegrityPacket(true);
dataEncryptor.setSecureRandom(new SecureRandom());
PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
OutputStream encryptedOut = encryptedDataGenerator.open(out, 4096);
PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(PGPCompressedData.UNCOMPRESSED);
OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[4096]);
PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(publicKey.getAlgorithm(), HashAlgorithmTags.SHA1);
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder);
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, secretKey);
boolean firstTime = true;
Iterator<String> it = publicKey.getUserIDs();
while (it.hasNext() && firstTime) {
PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, it.next());
signatureGenerator.setHashedSubpackets(spGen.generate());
firstTime = false;
}
signatureGenerator.generateOnePassVersion(false).encode(compressedOut);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
signatureGenerator.update(buf, 0, len);
}
in.close();
signatureGenerator.generate().encode(compressedOut);
compressedDataGenerator.close();
encryptedDataGenerator.close();
out.close();
}
public static void main(String args[]) {
Security.insertProviderAt(new BouncyCastleProvider(), 0);
byte inBytes[] = "The quick brown fox jumps over the lazy dog.".getBytes();
try {
RSAKeyPairGenerator kpg = new RSAKeyPairGenerator();
kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 1024, 90));
BcPGPKeyPair kp = new BcPGPKeyPair(PGPPublicKey.RSA_GENERAL, kpg.generateKeyPair(), new Date());
ByteArrayInputStream bais = new ByteArrayInputStream(inBytes);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ArmoredInputStream ais = new ArmoredInputStream(new ByteArrayInputStream(PGPPublicKeyString.getBytes()));
PGPPublicKeyRing pub = (PGPPublicKeyRing) new PGPObjectFactory(ais).nextObject();
signEncryptMessage(bais, baos, pub.getPublicKey(), kp.getPrivateKey());
System.out.println(new String(baos.toByteArray()));
} catch (Exception e) {
e.printStackTrace();
}
}
private static final String PGPPublicKeyString = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n"
+ "Version: GnuPG v2.0.19 (GNU/Linux)\n"
+ "\n"
+ "mQENBFJLq9IBCADvxNEfagIpxX+8bgXqKKxhjvT0c5WbgkJFyIP8LzkAwTrtQWiT\n"
+ "+5kpIi3xxf94zz4EyuDF5bsEwIJRNvamqcSARxvlEh4U2mTxafl8D7bPhyi476fZ\n"
+ "iFQTwOrK6lAtEboSE+lRMUoB04Lmh0IluhWmKumA6vOI7Mlg0JMbdS9G27kSrhBq\n"
+ "/TfHzQmjbt5WsunKagetzAFM+PXsceD1Yg69GPkRluuXs5LsmSdMpMT7wcK+sZgI\n"
+ "v9+3DbXRxdTQLUWL0g1yE58vMTlbiQ7z5i1jMVMq1YSYmThEW+cnoRmUUsle99ly\n"
+ "IX6IE0gvMySYxIaXTx9LRE538bD2E4UN9bIrABEBAAG0GXJlYWwgbmFtZSA8ZW1h\n"
+ "aWxAYWRkcmVzcz6JATkEEwECACMFAlJLq9ICGwMHCwkIBwMCAQYVCAIJCgsEFgID\n"
+ "AQIeAQIXgAAKCRD/zlUK7kqMk8XGCADMxe3WAUdd+qg4gAL5s+F/ziPozV8cVNP+\n"
+ "ThCHMvNkhoCYswzc30YcGAAsttvgYq7RlyG5yFdXFbo8wMEdDS6rQ72Ya7atNqKN\n"
+ "CB8VV3e87iN+Nv66HyZ59++d0GNO+yFvebmJoyhI2qZ05ng0m9ApZMpCUflhreXE\n"
+ "8+bGCg4fDECmOPnzbx2W68nFFXJEP8M7Bk8bD62Jtxto/hjg12Sv3HCbQMahR3mH\n"
+ "eTIHQUbySAQYBrEyshiv1Rcq+VDAJjO6EtkhxSo0w6T/FI475EdVg45G49wZ/FuX\n"
+ "FmuRqzLT5HGICaICQVxvvcrQ0c5WNwN0lnomoGOxxU73z810L74VuQENBFJLq9IB\n"
+ "CADevC5hdZ6IC8Cq773YsEME6QzIvHwsMVFb3IuUd7h/ZgglGwer6RwPl6lzF7w3\n"
+ "hiFVNysrQ542yEmB3gYk1ha/IVl/+OQg9DiNwN2e2Z3sp7vqapi42Qnbbt4HyQUY\n"
+ "di7l8uQzhEbtuvbKX2w1/P2EF/jLXOu9lSz4ZltElt39IgWejYkpLwVO3b3qpt7e\n"
+ "fuC9nvy12rW7iSUg+czqB16OdO7qKT1xvrAuxTT0LsJpHO1xQt91II8vNOxLSOft\n"
+ "RnX8097Zl0B7UWNTsPeecYbenmcLRTWNbzZaPMbMqEgUYqQEXJerBUIIom+lhPhm\n"
+ "EUtcPdioBXZs0OrbDp1vvVIbABEBAAGJAR8EGAECAAkFAlJLq9ICGwwACgkQ/85V\n"
+ "Cu5KjJM5iAf+OAkj/H6+SuRif356KlZFWjSzOdVtQvV96DbRWq3M18owK8Vq+7ee\n"
+ "wfGFNlBBnnqH4rYyqQUvac+358A0M+1lKdZXHZTLmpi48NeXUGe3AffTaFq7uOJr\n"
+ "P/IvV+06hRBMlAzuwMswG6hFQ9hjIGhas8lImJZZiuFaIauhCOHKe7/Ai6qLw4F6\n"
+ "7+i6QzExeeVmyoEBGqGA1KKmNJgZSq53X3T6yOQmXmAADj7wh1YdWh1r2dHXPc14\n"
+ "L1zehpW1497Dj5Fi4FCNxaKp9NEnIM9Cvv+2XN8gP//R7q0Tia2J6uxDRmMbtFK2\n"
+ "xG2RMc1kGXlWvre1qNASvr2ru7lQoQU8Iw==\n"
+ "=IsmN\n"
+ "-----END PGP PUBLIC KEY BLOCK-----\n";
}
和 gpg 命令行输出:
$ gpg -vvv -d test2
gpg: using character set `utf-8'
gpg: armor: BEGIN PGP MESSAGE
Version: BCPG v1.49
:pubkey enc packet: version 3, algo 1, keyid FFCE550AEE4A8C93
data: [2048 bits]
gpg: armor header:
gpg: public key is EE4A8C93
You need a passphrase to unlock the secret key for
user: "real name <email@address>"
2048-bit RSA key, ID EE4A8C93, created 2013-10-02
gpg: public key encrypted data: good DEK
:encrypted data packet:
length: 4129
mdc_method: 2
gpg: encrypted with 2048-bit RSA key, ID EE4A8C93, created 2013-10-02
"real name <email@address>"
gpg: CAST5 encrypted data
:trust packet: flag=e8 sigcache=00
gpg: ring trust w/o key
gpg: mdc_packet with invalid encoding
gpg: decryption failed: Invalid packet
任何帮助,将不胜感激。
干杯
拉莫