1

OpenSSL을 사용하여 타원 곡선 개인/공개 키 쌍을 생성했습니다. 개인 키와 공개 키는 PEM으로 인코딩됩니다. this. 공개 키를로드하는 방법을 알아 냈습니다.하지만 위의 메시지가 InvalidKeySpecException으로 끝나기 때문에 개인 키를로드하는 방법을 알 수 없습니다. 키 사양을 인식 할 수 없습니다.Elliptic Curve PEM으로 인코딩 된 개인 키를로드하려면 어떻게해야합니까?

나는 this을 찾았지만 "인코딩 된 키 사양이 인식되지 않음"으로 끝납니다. 개인 키를로드하려면 어떻게해야합니까?

-----BEGIN EC PRIVATE KEY----- 
MIGkAgEBBDD2MFRv6BpJU6/zDI2yBfVbe0oeU1nFAoYMedDGtcdwHyWNJSeiYRBA 
pVNzMxPSBLWgBwYFK4EEACKhZANiAAQBttEp/qUGnDlmL+o6KZnVs+RoBnEBEGho 
PxSUu1Xfj77QQqfuqHOCRzWXseQA1aZB/h6VQEiFovugtG1G3HaMxxrqLLxb10g2 
BMaRcAfZyeqc3O0Ui8XXb1esn0gOrCU= 
-----END EC PRIVATE KEY----- 
+0

내가 * 당신은 그냥 대신 PKCS # 8의 가장 최소한의 인코딩을 가지고 생각 * 준수 구조. Java에서 자신 만의 PKCS # 8을 만들고 온라인 ASN.1 디코더와 비교하십시오 (먼저 64를 기본으로 인코딩). –

+0

그래, 지금 확인해 보니 PKCS # 8 구조 안의 * X9.62 구조체입니다. –

+0

http://stackoverflow.com/questions/22963581/reading-elliptic-curve-private-key-from-file-with-bouncycastle/41947163 지금 개선됨 –

답변

2

귀하의 코드는 키 자체를 출력 : 여기에

private PrivateKey loadPrivateKey(String location) { 
    try { 
     // Strip the guarding strings 
     byte[] bytes = stripGuardLines(location); 

     return KeyFactory.getInstance("ECDH").generatePrivate(new PKCS8EncodedKeySpec(bytes)); 
    } catch (FileNotFoundException e) { 
     LoggerFactory.getLogger("Nectar").error("Failed to find Private KEY: " + location); 
     System.exit(1); 
    } catch (IOException e) { 
     LoggerFactory.getLogger("Nectar").error("IOException while loading Private Key!"); 
     e.printStackTrace(); 
     System.exit(1); 
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { 
     e.printStackTrace(); 
     System.exit(1); 
    } 

    return null; 
} 

private byte[] stripGuardLines(String location) throws IOException { 
    BufferedReader r = new BufferedReader(new FileReader(location)); 

    String line; 
    StringBuilder sb = new StringBuilder(); 
    while((line = r.readLine()) != null) { 
     if(line.contains("EC PRIVATE KEY")) { //Check if guard line 
      continue; 
     } 
     sb.append(line); 
    } 
    // Guard lines stripped, now decode base64 

    return Base64.getDecoder().decode(sb.toString()); 
} 

개인 키 파일입니다. PKCS # 8로 encode 된 비공개 키에 필요한 알고리즘 지정자가 없어졌습니다. 다행스럽게도 키 자체는 항상 인코딩 할 때 동일한 크기를 갖습니다 (ASN.1 정수는 사용하지 않습니다.이 정수는 볼 수있는 한 다른 크기를 가질 수 있습니다).

// static header you can put in front 
byte[] header = Hex.decode("30 81bf 020100 301006072a8648ce3d020106052b81040022 0481a7"); 
// your key from the PEM above 
byte[] fromPEM = Base64.decode("MIGkAgEBBDD2MFRv6BpJU6/zDI2yBfVbe0oeU1nFAoYMedDGtcdwHyWNJSeiYRBApVNzMxPSBLWgBwYFK4EEACKhZANiAAQBttEp/qUGnDlmL+o6KZnVs+RoBnEBEGhoPxSUu1Xfj77QQqfuqHOCRzWXseQA1aZB/h6VQEiFovugtG1G3HaMxxrqLLxb10g2BMaRcAfZyeqc3O0Ui8XXb1esn0gOrCU="); 
byte[] bytes = Arrays.concatenate(header, fromPEM); 
PrivateKey ecPrivate = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(bytes)); 

이 코드는 오라클 자바 JRE의 기본 구현과 호환 같은 탄력이 성 호환 둘 다 : 당신은 단순히 다른 키에서 헤더를 연결할 수 있다는 것을 의미한다

. 당신뿐만 아니라 당신의 키 쌍을 생성하는 오라클 호환 코드를 사용할 수 있습니다


참고 :

KeyPairGenerator kpGen = KeyPairGenerator.getInstance("EC"); 
kpGen.initialize(new ECGenParameterSpec("secp384r1")); 
KeyPair ecKP = kpGen.generateKeyPair(); 
+0

명백한 종류이지만 헤더에는 길이 인코딩과 명명 된 곡선의 OID가 포함되어 있기 때문에 secp384r1 (또는 P-384, 같은 것) 곡선에서만 작동합니다. –

+0

@ dave_thompson_085 아마 더 나은 방법은 대답을 투표 것입니다. 나의 선택은이 문제를 둘러싼 해킹에 더 가깝다. (직장에서'openssl'을 쓸어 버릴 시간이 없었다 : P). –

+0

(ninja) 또는 OpenSSL이 PEM :'openssl pkey pkcs8' (또는 특히 0.9.8 이하'openssl pkcs8 -topk8 -nocrypt pkcs8')을 변환 한 다음 strip and base64-decode하도록하십시오. 또는'openssl pkcs8 -topk8 -nocrypt -outform der pkcs8.der'를 사용하여 동시에 DER로 변환하여 직접 사용하십시오. 그러나 legacy/raw!를 출력하지 않는'pkey -outform der'는 없습니다. –

관련 문제