转换PGP公钥

时间:2016-11-27 17:41:12

标签: java bouncycastle x509 public pgp

有人知道是否有办法将pgp公钥格式的公钥转换为X.509密钥格式?也许使用Bouncy Castle或熟悉的东西?

因为我现在能够使用X509EncodedKeySpecs和PublicKey解码X.509公钥,但这不适用于PGP密钥格式。

byte[] decodeValue = Base64.decode(schluesselstring.getBytes(), Base64.DEFAULT);
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(decodeValue);
try {
    KeyFactory keyFact = KeyFactory.getInstance("RSA");
    try {
        PublicKey publicKey = keyFact.generatePublic(pubKeySpec);
        schluessel = "schluessel";
        Log.d("TEST", "publicKey = " + publicKey.toString());
        Log.d("TEST", "Algorithm = " + publicKey.getAlgorithm());
        Log.d("TEST", "Format = " + publicKey.getFormat());
      }
  catch...
  }

当我尝试在PGP密钥上使用此代码时,我收到错误消息,因为它不是ANSC.1。我也尝试使用不同的KeySpecs,但没有一个工作。

1 个答案:

答案 0 :(得分:1)

“X.509”(SPKI)和“PKCS8”密钥以及证书等其他内容使用的标准是Abstract Syntax Notation One ASN.1。标准Java加密不能处理PGP但是BouncyCastle(bcpg)可以做到这一点:

static void SO40831894 (String infile, String outfile) throws Exception {
    // adapted from org.bouncycastle.openpgp.examples.PubringDump
    try (InputStream in = new FileInputStream (infile)){
        PGPPublicKeyRingCollection    pubRings = new PGPPublicKeyRingCollection(
                PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator());
        Iterator<PGPPublicKeyRing>    rIt = pubRings.getKeyRings();
        while (rIt.hasNext()){
            PGPPublicKeyRing    pgpPub = (PGPPublicKeyRing)rIt.next();
            Iterator<PGPPublicKey>    it = pgpPub.getPublicKeys();
            while (it.hasNext()){
                PGPPublicKey    pgpKey = (PGPPublicKey)it.next();
                System.out.println(pgpKey.getClass().getName()
                        + " KeyID: " + Long.toHexString(pgpKey.getKeyID())
                        + " type: " + pgpKey.getAlgorithm()
                        + " fingerprint: " + new String(Hex.encode(pgpKey.getFingerprint())));
                BCPGKey bcKey = pgpKey.getPublicKeyPacket().getKey();
                /*System.out.println (bcKey.getClass().getName());*/
                if( bcKey instanceof RSAPublicBCPGKey ){
                    RSAPublicBCPGKey bcRSA = (RSAPublicBCPGKey)bcKey;
                    RSAPublicKeySpec specRSA = new RSAPublicKeySpec( bcRSA.getModulus(), bcRSA.getPublicExponent());
                    PublicKey jceKey = KeyFactory.getInstance("RSA").generatePublic(specRSA);
                    // if you want to use the key in JCE, use jceKey
                    // if you want to write "X.509" (SPKI) DER format to a file: 
                    Files.write(new File(outfile).toPath(), jceKey.getEncoded());
                    // if you want to write in PEM, bouncycastle can do that 
                    // or you can just do base64 and add BEGIN/END lines 
                    return; // assume only one key; if need to handle multiple keys
                    // or select other than the first, specify more clearly
                }
            }
        }       
    }