2017-06-19 189 views
7

我試圖將裝甲ECC gpg密鑰轉換爲相應的java類 ECPrivateKey/ECPublicKey。在java中解析Armored ECC公鑰/私鑰(由gpg cli生成)

爲了生成我使用的密鑰對:gpg --expert --full-generate-key

然後選擇(9)ECC和ECC(或(10)ECC(只登錄))

然後選擇(3)NIST P- 256

,導致:

-----BEGIN PGP PUBLIC KEY BLOCK----- 

mFIEWUdzwhMIKoZIzj0DAQcCAwQkAvZC1PIJ8ke1myyKhNny9vN78TIYo2MuAOY+ 
F38L9S3+Za9cKV/iIHOqfapbMoqdSmSnqDkevwQSr5MF2UOXtCJzaWduZWNjIChF 
Q0Mgc2lnbiBvbmx5KSA8c3NAc3MuY28+iJAEExMIADgWIQRiC+kefVkjnjKovKy5 
XANFl5+n1gUCWUdzwgIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRC5XANF 
l5+n1mzGAQDsgutymxDTTXPKFfpFFVp4fxacx1MSqxP71gNJYjguXwD8CEXD20Vm 
aU1WMi2jU7JC6oJn94Y4vWHwTLOU1zmQ19o= 
=swfS 
-----END PGP PUBLIC KEY BLOCK----- 

-----BEGIN PGP PRIVATE KEY BLOCK----- 

lHcEWUdzwhMIKoZIzj0DAQcCAwQkAvZC1PIJ8ke1myyKhNny9vN78TIYo2MuAOY+ 
F38L9S3+Za9cKV/iIHOqfapbMoqdSmSnqDkevwQSr5MF2UOXAAD9FhS2HZoWOyIi 
l9nj+WPa9S1o50jM5bNIRALzcyS8SgoP97Qic2lnbmVjYyAoRUNDIHNpZ24gb25s 
eSkgPHNzQHNzLmNvPoiQBBMTCAA4FiEEYgvpHn1ZI54yqLysuVwDRZefp9YFAllH 
c8ICGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AACgkQuVwDRZefp9ZsxgEA7ILr 
cpsQ001zyhX6RRVaeH8WnMdTEqsT+9YDSWI4Ll8A/AhFw9tFZmlNVjIto1OyQuqC 
Z/eGOL1h8EyzlNc5kNfa 
=qHBB 
-----END PGP PRIVATE KEY BLOCK----- 

如何從這個裝甲文本格式得到有效java.security.interfaces.ECPrivateKey和java.security.interfaces.ECP ublicKey的java類?

我的最終目標是通過以下方式簽署:

String createSignatureFromJson(String jsonPayload, byte[] privateKey) { 
     Payload payload = new Payload(jsonPayload) 
     def key = privateKeyParse(privateKey) 

     JWSSigner signer = new ECDSASigner((ECPrivateKey)key) 
     JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES256).build() 

     JWSObject jwsObject = new JWSObject(header, payload) 
     jwsObject.sign(signer) 
     jwsObject.signature 
    } 

回答

1
public static ECPrivateKey privateKeyParse(byte[] privateKey) throws Exception { 

     InputStream pgpIn = PGPUtil.getDecoderStream(new ByteArrayInputStream(privateKey)); 

     PGPObjectFactory pgpFact = new PGPObjectFactory(pgpIn, new JcaKeyFingerprintCalculator()); 
     PGPSecretKeyRing pgpSecRing = (PGPSecretKeyRing) pgpFact.nextObject(); 
     PGPSecretKey pgpSec = pgpSecRing.getSecretKey(); 

     PGPPrivateKey pgpPriv = pgpSec.extractPrivateKey(null); 

     JcaPGPKeyConverter converter = new JcaPGPKeyConverter(); 
     // this is the part i was missing from Peter Dettman's answer. pass BC provider to the converter 
     converter.setProvider(new BouncyCastleProvider()); 
     PrivateKey key = converter.getPrivateKey(pgpPriv); 
     return (ECPrivateKey) key; 
    } 
4

如果你只是通過在「私有密鑰塊」,這將提取ECPrivateKey:

private static ECPrivateKey privateKeyParse(byte[] privateKey) throws Exception 
{ 
    InputStream pgpIn = PGPUtil.getDecoderStream(new ByteArrayInputStream(privateKey)); 

    PGPObjectFactory pgpFact = new PGPObjectFactory(pgpIn, new JcaKeyFingerprintCalculator()); 
    PGPSecretKeyRing pgpSecRing = (PGPSecretKeyRing)pgpFact.nextObject(); 
    PGPSecretKey pgpSec = pgpSecRing.getSecretKey(); 
    PGPPrivateKey pgpPriv = pgpSec.extractPrivateKey(null); 

    return (ECPrivateKey)new JcaPGPKeyConverter().getPrivateKey(pgpPriv); 
} 

要回答評論問題如何獲得'privateKey',如果整個:

-----BEGIN PGP PRIVATE KEY BLOCK----- 
... 
-----END PGP PRIVATE KEY BLOCK----- 

是在一個文件,然後只是讀取整個文件轉換成一個byte []:

InputStream fIn = new BufferedInputStream(new FileInputStream(...)); 
byte[] privateKey = org.bouncycastle.util.io.Streams.readAll(fIn); 
+0

你能具體談談如何從私有密鑰塊獲取到的byte []專用密鑰參數? –

+0

我得到java.io.IOException異常:未知的PGP公鑰算法遇到了 :PGPSecretKeyRing pgpSecRing =(PGPSecretKeyRing)pgpFact.nextObject() 提供的私有密鑰塊的方法,通過以下方式時: privateKeyBlock。 split('\ n')。join()。bytes –

+0

你使用什麼版本的BC?我認爲PGP EC密鑰只能在1.50左右支持。 –