2013-09-04 4 views
26

에 .P12 파일에서의 PrivateKey 객체를 얻기. 자격 증명이 API에 연결되도록하려면 .setServiceAccountPrivateKey (PrivateKey privateKey) 필드가 있습니다. 그럼 내가 할 수있는 가장 쉬운 방법은 뭔가? 나는 내 classpath에있는 resources 폴더를 가지고있다. 그래서 p12 파일을 거기에 추가하면 getClass(). getResource()로부터 리소스를 inputStream 또는 URL로 얻을 수있다. URL 메서드를 시도했지만 작동하지 않습니다. URL.toURI()에서 File 개체를 만들려고하면 "URI가 계층 적이 지 않습니다"오류가 발생합니다.는 제목에서 알 수 있듯이, 나는 구글 서비스 계정 API 액세스에 필요한 .P12 파일이 자바

답변

45

당신은 ClassLoader.getResourceAsStream(String) 방법을 사용하여 .P12 파일을로드 키 스토어에로드하고는 키 스토어에서 키를 얻을 수 있습니다. 어떤 위치에서

KeyStore keystore = KeyStore.getInstance("PKCS12"); 
keystore.load(this.getClass().getClassLoader().getResourceAsStream("keyFile.p12"), p12Password.toCharArray()); 
PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, p12Password.toCharArray()); 

ClassLoader.getResourceAsStream(String)로드 자원은 파일의 경로를 지정할 필요가 없습니다, 그들은 클래스 경로에 이미있어 제공.

keyAlias는 개인 키에 대응하여 P12 파일에있는 항목의 이름입니다. PKCS12 파일은 여러 항목을 포함 할 수 있으므로 액세스 할 항목을 나타내는 방법이 필요합니다. 별칭은 이것이 어떻게 달성되는지입니다.

개인 키의 별칭이 무엇인지 확실하지 않은 경우 명령 줄의 keytool 유틸리티를 사용하여 p12 파일의 내용을 나열 할 수 있습니다. 이 도구는 모든 JRE 및 JDK 설치에 포함되어 있습니다.

keytool -list -keystore keyFile.p12 -storepass password -storetype PKCS12 

출력

Keystore type: PKCS12 
Keystore provider: SunJSSE 

Your keystore contains 1 entry 

yourKeyAlias, Sep 4, 2013, PrivateKeyEntry, 
Certificate fingerprint (MD5): 48:A8:C4:12:8E:4A:8A:AD:58:81:26:90:E7:3D:C8:04 
+0

이 암호화 방법에 익숙하지 않은 경우 ... keyAlias ​​란 무엇입니까? – gratsby

+0

키 스토어의 내용을 나열하여 별명을 찾는 방법에 대한 정보가 추가되었습니다. – Syon

+0

감사! 그것은 완벽하게 작동했습니다. – gratsby

4

당신은 당신이 마지막 keyAlias 요소를 찾아야한다 (예를 들어, 당신이 공급자로 BouncyCastle을 사용하고 있습니다.) getKey()에서 null 얻을 경우

KeyStore keystore = KeyStore.getInstance("PKCS12", "BC"); 
keystore.load(this.getClass().getClassLoader().getResourceAsStream("keyFile.p12"), p12Password.toCharArray()); 
Enumeration aliases = keystore.aliases(); 
String keyAlias = ""; 
while (aliases.hasMoreElements()) { 
    keyAlias = (String) aliases.nextElement(); 
} 
PrivateKey key = (PrivateKey)keystore.getKey(keyAlias, pass); 
8

내가이 생각을 Google의 SecurityUtils를 직접 쉽게 호출 할 수 있습니다 (예 :

).
PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), this.getClass().getResourceAsStream("keyFile.p12"), "notasecret", "privatekey", "notasecret") 

이 한 줄 그리고 당신은 앨리어싱에 대해 걱정할 필요가 없습니다.

+2

패스워드를 넣어 주셔서 고마워요, 나는 그것을 잊어 버렸다고 걱정했습니다. – dhakim

+0

@Robert Watts 그래서이 호출에서 "privatekey"를 별칭으로 사용합니다. privateKey가 pkcs12 키의 기본 별칭이기 때문입니까? 검색했지만 찾은 문서가 없습니다.keytool을 실행했고 별칭은 사실 "개인 키"였지만 항상 새로운 키가 있는지 확인하고 싶습니다. –

+0

@UsmanMutawakil pkcs12 파일 형식에 대한 표준 기본 별칭이 없다고 생각합니다. Keytool은 별칭으로 기본 설정되어있을 수 있으며, 다른 도구/프로그램도 마찬가지이지만 파일 형식이 본질적으로 아닙니다. –

1

위의 제안 나를 위해 작동하지 않았다. 그런 다음 http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm에서 시도해 보았습니다. 복사하여 붙여 넣기 복사

import java.io.FileInputStream; 
import java.security.Key; 
import java.security.KeyPair; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.cert.Certificate; 

public class Main { 
    public static void main(String[] argv) throws Exception { 
    FileInputStream is = new FileInputStream("your.keystore"); 

    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
    keystore.load(is, "my-keystore-password".toCharArray()); 

    String alias = "myalias"; 

    Key key = keystore.getKey(alias, "password".toCharArray()); 
    if (key instanceof PrivateKey) { 
     // Get certificate of public key 
     Certificate cert = keystore.getCertificate(alias); 

     // Get public key 
     PublicKey publicKey = cert.getPublicKey(); 

     // Return a key pair 
     new KeyPair(publicKey, (PrivateKey) key); 
    } 
    } 
}