Java : 如何从 .asc 文件创建 java.security.Key?

Java : how to create java.security.Key from .asc file?

我必须将文件加密为 pgp 格式。我有 .asc 格式的 public 密钥 .

密码 init() 方法需要传入一个 public 密钥。使用文件创建该密钥的方法是什么。就我而言,它是 .asc 文件。

    Cipher cipher;
    Key publicKey = null;

    try 
    {
        cipher = Cipher.getInstance("RSA", "BC");




    } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException e) {
        String msg = "failed to create output stream";
        LOGGER.error( msg, e );
        throw new RuntimeException( msg, e );
    }

    try {
        publicKey = getPublicKey(publicKeyPath);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return ( new CipherOutputStream(outputStream, cipher));

我遇到错误: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: 密钥格式无效

我的 getPublicKey 方法看起来像(但我认为,我不必这样做,因为文件本身有 public 密钥)

public static PublicKey getPublicKey(String filename)
        throws Exception {

        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());

        X509EncodedKeySpec spec =
          new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        return kf.generatePublic(spec);
      } 

Public_key.asc 看起来像:

            -----BEGIN PGP PUBLIC KEY BLOCK-----
            Version: Encryption Desktop 10.3.2 (Build 16127)

            mQENBFYhXNoBCACgX/u03wm8cLqmTZiKGx6H/1ZUoBsfaDB2rdG2D8jYQzvaq4MA
            hZWBEVhA2BGKrNI+a2SDhKGAY4OK7aUZVAVG1bfQNVdNe80TbEF8g/wO2FreYPkb
            ojPtkwgyzsvb1BKwgRM1UMjkM5OWnhAPDhFDc39SFbmHLsXrURqFqJd9T3xzF6ty

            ................................................................


            D4WXvHpPXCJcwCBe+/81ZpjxlrLkUu8bO79jxZdKcI5ZRpmIe/VPJoDUVKLvl9n3
            ANvDJGdGcW3x6RyL9QOnoRDf6njimqcTm8UqImdLCz4TFdv94dvM4K0NOWuFdYal
            E9Q+U0Q7aiaWn+Kt+OYpd6++m7wnJRH/q0H69LIR9v3Td3udzOaxv/gzXF1BFuAS
            DQs6iA==
            =ckOV
            -----END PGP PUBLIC KEY BLOCK-----

此键的属性如下:

Robert 和 Maarten Bodewes 的回复是可行的方法之一。

我的 public 密钥在 .asc 文件中,私钥在 .skr(密钥环)中

我是这样实现的并且对我有用:

                public static PublicKey getPublicKey(
                    String filePath)
                    throws PGPException, NoSuchProviderException, FileNotFoundException, IOException
                {
                    PGPPublicKey    encKey = readPublicKey(new FileInputStream(filePath));
                    return new JcaPGPKeyConverter().setProvider("BC").getPublicKey(encKey);
                }




                public static PrivateKey getPrivateKey( 
                        InputStream    in, char[]      passwd) 
                        throws IOException, PGPException, NoSuchProviderException 
                    { 
                        in = PGPUtil.getDecoderStream(in); 

                        PGPSecretKeyRingCollection        pgpSec = new PGPSecretKeyRingCollection(in); 

                        // 
                        // we just loop through the collection till we find a key suitable for encryption, in the real 
                        // world you would probably want to be a bit smarter about this. 
                        // 

                        // 
                        // iterate through the key rings. 
                        // 
                        Iterator<?> rIt = pgpSec.getKeyRings(); 

                        while (rIt.hasNext()) 
                        { 
                            PGPSecretKeyRing    kRing = (PGPSecretKeyRing)rIt.next();     
                            Iterator<?>                        kIt = kRing.getSecretKeys(); 

                            while (kIt.hasNext()) 
                            { 
                                PGPSecretKey    k = (PGPSecretKey)kIt.next(); 

                                if (k != null) 
                                { 
                                    PGPPrivateKey pk = k.extractPrivateKey(passwd, "BC"); 
                                     return new JcaPGPKeyConverter().setProvider("BC").getPrivateKey(pk);
                                } 
                            } 
                        } 

                        throw new IllegalArgumentException("Can't find secured key in key ring."); 
                    } 

                public static PGPPublicKey readPublicKey( 
                        InputStream    in) 
                        throws IOException, PGPException 
                    { 
                        in = PGPUtil.getDecoderStream(in); 

                        PGPPublicKeyRingCollection        pgpPub = new PGPPublicKeyRingCollection(in); 

                        // 
                        // we just loop through the collection till we find a key suitable for encryption, in the real 
                        // world you would probably want to be a bit smarter about this. 
                        // 

                        // 
                        // iterate through the key rings. 
                        // 
                        Iterator<?> rIt = pgpPub.getKeyRings(); 

                        while (rIt.hasNext()) 
                        { 
                            PGPPublicKeyRing    kRing = (PGPPublicKeyRing)rIt.next();     
                            Iterator<?>                        kIt = kRing.getPublicKeys(); 

                            while (kIt.hasNext()) 
                            { 
                                PGPPublicKey    k = (PGPPublicKey)kIt.next(); 

                                if (k.isEncryptionKey()) 
                                { 
                                    return k; 
                                } 
                            } 
                        } 

                        throw new IllegalArgumentException("Can't find encryption key in key ring."); 
                    }