带bouncycastle的java签名公共pgp密钥

带bouncycastle的java签名公共pgp密钥,java,bouncycastle,pgp,Java,Bouncycastle,Pgp,我有一个疑问。。 我必须使用BouncyCastleAPI签署pgp公钥。 现在:据我所知,用另一种方法对密钥进行签名最终会在公钥中添加一个“证书”。 由于没有别的办法,我只好在图书馆里瞎找。 到目前为止,我唯一的发现是PGPSignatureGenerator内部的方法generateCertification。但此方法会在主PgpPublicKey和另一个PgpPublicKey之间生成证书。。这让我觉得很奇怪: 我假设为了信任另一个公钥,它必须使用您自己的私有pgp密钥进行签名,就像在常规

我有一个疑问。。 我必须使用BouncyCastleAPI签署pgp公钥。 现在:据我所知,用另一种方法对密钥进行签名最终会在公钥中添加一个“证书”。 由于没有别的办法,我只好在图书馆里瞎找。 到目前为止,我唯一的发现是PGPSignatureGenerator内部的方法generateCertification。但此方法会在主PgpPublicKey和另一个PgpPublicKey之间生成证书。。这让我觉得很奇怪: 我假设为了信任另一个公钥,它必须使用您自己的私有pgp密钥进行签名,就像在常规的x.509中使用CA认证一样。。 这是我在尝试从其他库获取一些想法时看到的一些方法的假设:例如,didisoft在密钥库上有一个类似的方法,您必须提供PgpPrivatekey密钥UID

有人有什么建议或代码吗?
提前感谢。

这里有一个签署公钥的代码示例:

    PGPSecretKey mySecretKey;
    PGPPublicKey publicKeyToBeSigned; 
    PGPPrivateKey pgpPrivKey = mySecretKey
            .extractPrivateKey(new JcePBESecretKeyDecryptorBuilder()
                    .setProvider("BC").build("password for your private key"));
    PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
            new JcaPGPContentSignerBuilder(mySecretKey.getPublicKey()
                    .getAlgorithm(), PGPUtil.SHA512));
    signatureGenerator.init(PGPSignature.DIRECT_KEY, pgpPrivKey);

    PGPSignature signature = signatureGenerator.generateCertification(
            id, publicKeyToBeSigned);
这段代码只是创建了签名。您需要将其添加到公钥中,然后:

PGPPublicKey.addCertification(publicKeyToBeSigned, signature);

希望对您有所帮助:)

这可用于检查一个密钥是否为另一个密钥提供了默认证书

  /**
 * Signs a public key
 *
 * @param publicKeyRing a public key ring containing the single public key to sign
 * @param id the id we are certifying against the public key
 * @param secretKey the signing key
 * @param secretKeyPassword the signing key password
 *
 * @return a public key ring with the signed public key
 */
public static PGPPublicKeyRing signPublicKey( PGPPublicKeyRing publicKeyRing, String id, PGPSecretKey secretKey,
                                              String secretKeyPassword ) throws PGPException
{
    try
    {
        PGPPublicKey oldKey = publicKeyRing.getPublicKey();

        PGPPrivateKey pgpPrivKey = secretKey.extractPrivateKey(
                new JcePBESecretKeyDecryptorBuilder().setProvider( provider )
                                                     .build( secretKeyPassword.toCharArray() ) );

        PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
                new JcaPGPContentSignerBuilder( secretKey.getPublicKey().getAlgorithm(), PGPUtil.SHA1 ) );

        signatureGenerator.init( PGPSignature.DEFAULT_CERTIFICATION, pgpPrivKey );

        PGPSignature signature = signatureGenerator.generateCertification( id, oldKey );

        PGPPublicKey newKey = PGPPublicKey.addCertification( oldKey, signature );

        PGPPublicKeyRing newPublicKeyRing = PGPPublicKeyRing.removePublicKey( publicKeyRing, oldKey );

        return PGPPublicKeyRing.insertPublicKey( newPublicKeyRing, newKey );
    }
    catch ( Exception e )
    {
        //throw custom  exception
        throw new PGPException( "Error signing public key", e );
    }
}


/**
 * Verifies that a public key is signed with another public key
 *
 * @param keyToVerify the public key to verify
 * @param id the id we are verifying against the public key
 * @param keyToVerifyWith the key to verify with
 *
 * @return true if verified, false otherwise
 */
public static boolean verifyPublicKey( PGPPublicKey keyToVerify, String id, PGPPublicKey keyToVerifyWith )
        throws PGPException
{
    try
    {
        Iterator<PGPSignature> signIterator = keyToVerify.getSignatures();
        while ( signIterator.hasNext() )
        {
            PGPSignature signature = signIterator.next();
            signature.init( new JcaPGPContentVerifierBuilderProvider().setProvider( provider ), keyToVerifyWith );
            if ( signature.verifyCertification( id.getBytes(), keyToVerify ) )
            {
                return true;
            }
        }
        return false;
    }
    catch ( Exception e )
    {
        //throw custom  exception
        throw new PGPException( "Error verifying public key", e );
    }
}
/**
*签署公钥
*
*@param publicKeyRing包含要签名的单个公钥的公钥环
*@param id我们根据公钥验证的id
*@param secretKey签名密钥
*@param secretKeyPassword签名密钥密码
*
*@返回带有签名公钥的公钥环
*/
public static PGPPublicKeyRing signPublicKey(PGPPublicKeyRing publicKeyRing publicKeyRing,String id,PGPSecretKey secretKey,
字符串secretKeyPassword)引发PGPException
{
尝试
{
PGPPublicKey oldKey=publicKeyRing.getPublicKey();
PGPPrivateKey pgpPrivKey=secretKey.extractPrivateKey(
新的JcePBESecretKeyDecryptorBuilder().setProvider(提供程序)
.build(secretKeyPassword.toCharArray());
PGPSignatureGenerator signatureGenerator=新PGPSignatureGenerator(
新的JcaPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(),PGPUtil.SHA1));
signatureGenerator.init(PGPSignature.DEFAULT_认证,pgpPrivKey);
PGPSignature signature=signatureGenerator.generateCertification(id,旧密钥);
PGPPublicKey newKey=PGPPublicKey.addCertification(旧密钥,签名);
PGPPublicKeyRing newPublicKeyRing=PGPPublicKeyRing.removePublicKey(publicKeyRing,oldKey);
返回PGPPublicKeyRing.insertPublicKey(newPublicKeyRing,newKey);
}
捕获(例外e)
{
//抛出自定义异常
抛出新的PGPException(“错误签名公钥”,e);
}
}
/**
*验证是否使用另一公钥对公钥进行签名
*
*@param key验证要验证的公钥
*@param id我们正在根据公钥验证的id
*@param keytovirify使用要验证的密钥
*
*@验证后返回true,否则返回false
*/
公共静态布尔校验公钥(PGPPublicKey keytovify,字符串id,PGPPublicKey keytovifywith)
抛出PGPException
{
尝试
{
迭代器signIterator=keytovify.getSignatures();
while(signIterator.hasNext())
{
PGPSignature signature=signIterator.next();
signature.init(新的JcaPGPContentVerifierBuilderProvider().setProvider(provider),keyToVerifyWith);
if(signature.verifyCertification(id.getBytes(),keyToVerify))
{
返回true;
}
}
返回false;
}
捕获(例外e)
{
//抛出自定义异常
抛出新的PGPException(“验证公钥时出错”,e);
}
}

为什么要签署公钥?通常你要么使用私钥对邮件(或文件)进行签名(以证明你发送的邮件(或文件)没有被更改),要么使用收件人的公钥对你发送给他的邮件(或文件)进行加密(只有他的私钥才能解密)。嗯,也许是我没有完全弄清楚pgp的概念。。。我的意思是,你想信任某人的密钥,并说他们的密钥对你来说是“好的”,基本上是CA概念的等价物。。在这种情况下,您需要对其公钥进行签名。。身份的“信任”值由签名该pgp公钥的接收者/接收者数量给出。。这就是为什么我认为你需要签一把钥匙。我很可能明天晚些时候再查。。我已经猜到了一个与此类似的代码,唯一的区别是我没有首先运行init。。(我注意到,对于其他行动,如验证撤销证书时,这也是强制性的)。。。我会让你知道的。现在。。。如果我想反过来说:我有一个由key1签名的key2。。我尝试了以下方法[code]BcPGPContentVerifierBuilderProvider verifierBuilderProvider=new BcPGPContentVerifierBuilderProvider();signature.init(verifierBuilderProvider,signedKey);布尔结果匹配=signature.verifyCertification(authorKey,signedKey);[/code]但不幸的是,它不起作用。。有什么建议吗?有趣的是:你做的和我做的完全一样的失败;)。我身上没有密码,但要验证签名,你需要两个公钥。签名者和签名者!一个转到init,另一个转到verifyCertification。如果你不明白,我可以在今天或明天晚上发布一个例子。如果我的代码示例对您有效,那么您最好将我的答案标记为已接受。当然,我将您的答案标记为已接受!谢谢你花时间回答我!第二点的代码示例是非常受欢迎的,但事实上你帮了我很多。。pgp和bouncycastle api的样本数量之多(或者我应该说缺乏…)让我非常震惊。。我是说,b