Key 인터페이스
JCA에서 지원하는 모든 키는 Java.Security.Key 인터페이스로 추상화된다.
Key 인터페이스는 getAlgorithm(), getFormat(), getEncoded() 를 제공하며, 제한된 키정보에 대한 접근만 허용하고 있다.
1 2 3 4 5 6 7 | KeyPair keyPair = rsaUtil.generateKeyFair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); log.info("algorithm : {}", privateKey.getAlgorithm()); log.info("format : {}", privateKey.getFormat()); log.info("encoded : {} ", Base64.encodeBase64String(privateKey.getEncoded())); | cs |
(여기서 rsaUtil은 따로 만든 클래스이고, generateKeyFair()는 RSA형식의 KeyPair를 리턴하는 메소드이다.)
- 결과
1 2 3 | algorithm : RSA format : PKCS#8 encoded : MIIEvgIBADANBgkqhkiG9w0BAQEFAASCB............이하 생략 | cs |
KeyPair 클래스
KeyPair 클래스는 단순히 키 쌍을 보관하고 접근할 수 있는 역할을 한다. 위에 코드의 getPrivate(), getPublic() 제공
Key Specification 인터페이스와 구현 클래스
모든 키는 Key객체와 KeySpec 객체로 표현할 수 있다. (표현 방법의 차이)
Cipher 클래스는 Key 객체를 사용해 암호화 알고리즘을 초기화 하지만 Key 객체는 전송과 저장에 용이한 포맷으로 변환이 필요한 상황이 있다. (Base64인코딩 하여 보낸 다거나..)
이런경우 KeySpec 인터페이스가 유용하다. KeySpec 인터페이스는 알고리즘 스펙에 따라 정의된 get 메서드를 통해 키 구성 요소에 개별적으로 접근할 수 있다.
DER과 PEM(Privacy Enhanced Mail)
개인키 또는 인증서를 추출할 때 DER 또는 PEM 포멧이 사용된다.
개인키나 인증서는 ASN.1 문법으로 표시되는데, 이를 DER로 인코딩한 것이 DER파일이다. PEM 파일은 바이너리 형식의 DER파일을 출력 가능한 텍스트 문자로 저장한 파일을 말한다.
PrivateKey를 PEM 형식으로 만들었을 경우(PKCS8 방식)
-----BEGIN PRIVATE KEY-----
Base64인코딩 문자열
-----END PRIVATE KEY-----
과 같은 형식으로 나타난다.
DER
ASN.1 DER 형식이며 바이너리 형태로 저장
KeySpec 인터페이스에 대한 구체적인 기능들은 KeySpec 인터페이스를 상속한 다른 인터페이스들에서 명세하고 있다.
EncodedKeySpec 인터페이스는 KeySpec 인터페이스를 상속한 것이다. 이 인터페이스는 DER로 인코딩한 공개 키 또는 개인 키를 표현하기 위한 것이다.
이 인터페이스의 getEncoded() 메서드는 DER로 인코딩된 키를 바이트 배열로 반환한다.
EncodedKeySpec 인터페이스의 대표적인 구현체로는 PKCS8EncodedKeySpec과 X509EncodedKeySpec이 있으며, 두 구현체의 DER 인코딩 방식은 동일하다.
인코딩 대상이 각각 개인키(PKCS8EncodedKeySpec)와 공개키(X509EncodedSpec)이라는 차이점이 있다.
PKCS8EncodedKeySpec과 X509EncodedSpec
PKCS8EncodedKeySpec 클래스는 개인키를 표현하기 위한 것이며, PKCS#8는 개인키를 표현하기 위한 표준으로 ASN.1로 기술되어 있다. (PKCS#8표준이 정의한 PrivateKeyInfo 규칙에 따라 개인키를 DER로 인코딩)
X509EncodedSpec 클래스는 공개 키를 표현하기 위한 것이며, X509는 공개키를 표현하기 위한 표준으로 ASN.1로 기술되어 있다. (X509 표준이 정의한 SubjectPublicKeyInfo 규칙에 따라 공개 키를 DER로 인코딩)
Generator와 Factory의 용어적 차이
JCA에서 키를 생성하는 방법으로 Generator와 Factory를 이용하는 방법이 존재한다.
Generator는 완전히 새로운 객체를 생성할 때 사용한다.
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
필요에 따라 '키 알고리즘 특성 의존적인 방식' 과 '키 알고리즘 독립적인 방식'이 존재한다.
'의존적인 방식' 이란 키 알고리즘을 사용할 때 여러 인자들을 직접 지정하는 것을 말하고,
'독립적인 방식'이란 키 키사이즈와 랜덤구현체만을 사용자에게 지정하게 하고 나머지 인자들은 Geneator 내부 자체에서 생성하여 키가 생성되도록 하는 것이다.
Factory는 어떤 키 데이터 객체를 다른 타입의 키 데이터 객체로 전환하는데 사용한다. 예를 들어 인증서 바이트 배열을 X509Certificate객체로 전화하기 위해 CertificateFactory를 사용할 수 있다. (밑에 코드 참고)
(이미지출처)
KeyFactory 클래스와 SecretKeyFactory클래스
KeyFactory 클래스는 Key 객체를 KeySpec 객체로, KeySpec 객체를 Key 객체로 상호 변환하는 기능을 제공한다.
(이미지출처)cs
1 2 3 4 | X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyPemStr)); KeyFactory kf = KeyFactory.getInstance("RSA"); publicKey = kf.generatePublic(keySpec); // public Key 생성 | cs |
하나의 키 데이터는 호환 가능한 여러 종류의 KeySpec으로 표현이 된다.
DSA PublicKey는 DSAPublicKeySpec과 X509EncodedKeySpec 객체 포맷으로 나타낼 수 있다.
SecretKeyFactory 클래스는 비밀키(대칭키) 관련 팩토리다.
KeyPariGenerator클래스는 공개키와 개인키를 포함하는 키 쌍(KeyPair)를 신규로 생성하는 엔진 클래스이다.
KeyGenerator는 대칭키 알고리즘의 비밀키를 생성하는데 사용되는 엔진 클래스이다.
(이미지출처)
CertificateFactory 클래스
'프로그래밍 노트 > JAVA' 카테고리의 다른 글
[JAVA] 컬렉션프레임워크(CollectionFramework) 4 - TreeSet (0) | 2018.09.12 |
---|---|
[JAVA] 컬렉션프레임워크(CollectionFramework) 3 - HashSet (0) | 2018.09.12 |
[JAVA] JCA(Java Cryptography Architecture) 자바 암호화와 보안 (0) | 2018.09.05 |
[JAVA] 컬렉션프레임워크(CollectionFramework) 2 (0) | 2018.08.13 |
[JAVA] 네트워크 프로그래밍 TCP 소켓 통신 (5) | 2018.07.08 |