2013-10-28 2 views
7

내 응용 프로그램에서 공용/개인 키 쌍을 생성하고 디스크에 나중에 사용하기 위해 저장합니다. 개인 키를로드하고 다시 초기화하면 제대로 작동하지만 개인 키의 경우 알 수없는 KeySpec 유형이 있습니다. java.security.spec.PKCS8EncodedKeySpec - 이유를 모르겠습니다.파일에서 공개 키 데이터로드

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(4096); 
KeyPair keyPair = kpg.generateKeyPair(); 
privKey =keyPair.getPrivate(); 
pubKey =keyPair.getPublic();   

DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PRIVKEY_FILE,Context.MODE_PRIVATE)); 
byte[] data=privKey.getEncoded(); 
out.write(data); 
out.close(); 

DataOutputStream out=new DataOutputStream(ctx.openFileOutput(PUBKEY_FILE,Context.MODE_PRIVATE)); 
byte[] data=pubKey.getEncoded(); 
out.write(data); 
out.close(); 

개인 키의 다음로드가 잘 작동 :

DataInputStream in=new DataInputStream(ctx.openFileInput(PRIVKEY_FILE)); 
byte[] data=new byte[in.available()]; 
in.readFully(data); 

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
privKey = kf.generatePrivate(keySpec); 

decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
decryptCipher.init(Cipher.DECRYPT_MODE, privKey); 

유사 코드 내가 키 (쉬울 단순화 조금 읽을 수있는 코드)를 생성하고 저장하는 방법은

공개 키가 비참하게 실패합니다.

DataInputStream in=new DataInputStream(ctx.openFileInput(PUBKEY_FILE)); 
byte[] data=new byte[in.available()]; 
in.readFully(data); 

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); 
KeyFactory kf = KeyFactory.getInstance("RSA"); 
pubKey = kf.generatePublic(keySpec); --> here the exception is thrown 

encryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
encryptCipher.init(Cipher.ENCRYPT_MODE, pubKey);    

그래서 내가 뭘 잘못하고 있니? 디스크에서 공개 키 데이터를로드하는 올바른 방법은 무엇입니까?

감사합니다.

답변

14

공개 키와 비공개 키는 서로 다른 방식으로 인코딩됩니다. 개인 키는 PKCS # 8에서 인코딩되지만 공개 키는 암호화되지 않습니다. 대신 ASN.1 사양에 따라 X.509로 인코딩됩니다. Key.getFormat() 메소드에서

설명 :

은 기본 인코딩이 키 방식,이 키 암호화를 지원하지 않는 경우는 null의 이름을 반환. 기본 인코딩 형식은이 키에 대한 ASN.1 사양이 존재하는 경우 적절한 ASN.1 데이터 형식으로 명명됩니다. 예를 들어 공개 키에 대한 ASN.1 데이터 형식의 이름은 X.509 표준에 정의 된 SubjectPublicKeyInfo입니다. 이 경우 반환되는 형식은 "X.509"입니다. 마찬가지로, 개인 키에 대한 ASN.1 데이터 형식의 이름은 PKCS # 8 표준에 정의 된 PrivateKeyInfo입니다. 이 경우 반환되는 형식은 "PKCS # 8"입니다.

이에 따르면 공개 키를 PKCS # 8로 읽는 대신 X.509로 읽어야합니다.

PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(data); 

에 :

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(data); 

은 공개 키 읽기 코드를 변경 고려
관련 문제