第一个坑:生产上业务要求用的是子密钥加密文件。
@SuppressWarnings("unchecked") public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
PGPPublicKeyRingCollection keyRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in)); PGPPublicKey publicKey = null;
IteratorrIt = keyRingCollection.getKeyRings();
while (publicKey == null && rIt.hasNext()) {
PGPPublicKeyRing kRing = rIt.next();
IteratorkIt = kRing.getPublicKeys();
while (publicKey == null && kIt.hasNext()) {
PGPPublicKey key = kIt.next();
if (key.isEncryptionKey()) {
//重点在这里面,从公钥环上面取到的公钥对象是有俩个的,遍历时第一个是主密钥,而我们需要的是子密钥,也就是第二个。可是查看源码,并没有判断是否子密钥的方法。最后找到一个,判断是否主钥的方法。所以,子密钥加密时的获取密钥的逻辑修改为:
if(!key.isMasterKey()){
//子密钥
publicKey = key;
}
}
}
}
if (publicKey == null) {
throw new IllegalArgumentException("Can't find public key in the key ring.");
}
if (!isForEncryption(publicKey)) {
throw new IllegalArgumentException("KeyID " + publicKey.getKeyID() + " not flagged for encryption.");
}
return publicKey;
}
第二个坑:读取公钥文件时,抛错
...... found where PGPPublicKeyRing expected
查看源代码:
if (!(obj instanceof PGPPublicKeyRing))
{
throw new PGPException(obj.getClass().getName() + " found where PGPPublicKeyRing expected");
}
解决方法:对方所给的公钥文件的问题,没有公钥环对象。