790 likes | 956 Views
Key Managemnet. 소프트웨어공학 실험실 김경태, 전은아, 민병도. 목 차. 소 개 Keys Key Generators 와 Translators Key Agreement The Identity Key Management Paradigm The KeyStore Key Management Paradigm 결 론. 구성. The KeyStore Key Management Paradigm. Keys Key Generators Key Translators
E N D
Key Managemnet 소프트웨어공학 실험실 김경태, 전은아, 민병도
목 차 • 소 개 • Keys • Key Generators와 Translators • Key Agreement • The Identity Key Management Paradigm • The KeyStore Key Management Paradigm • 결 론
구성 The KeyStore Key Management Paradigm Keys Key Generators Key Translators Key Agreement The Identity Key Management Paradigm 소 개 • 배경: 개인정보의 보호를 위하여 암호 키 사용하게 되었고, 따라서 암호 키의 관리 문제가 나타남. Sun은 키 관리를 위한 인터페이스와 클래스를 제공(JDK). JDK class와interface가 키를 관리하고 표현하는데 사용
javax.crypto.SecretKey javax.crypto 인터페이스 Public String getAlgorithm() Public byte[] getEncoded() Public String getFormat() Keys(1/3) java.security 클래스 인터페이스 java.security. KeyPair java.security.Key public PublicKey getPublic() public PivateKey getPrivate() java.security.PublicKey java.security.PrivateKey
java.crypto.SecuretKey 인터페이스 - 비밀 키에 사용되는 인터페이스 (개인 또는 세션 키) Keys(2/3) • java.security.Key인터페이스 • - 모든 키의 공통적 기능을 정의하는 인터페이스 • 메소드 public String getAlgorithm() - 키에서 사용된 암호 알고리즘 리턴 (예:DSA, DSA, MD5, RSA 등) public byte[] getEncoded() - 암호화된 값 리턴 ( 암호화는 바이트 배열에 키 값을 적용) public String getFormat() - 암호화에 사용된 키 포맷의 이름 리턴(예:X.509, PKCS#8)
JDK 인터 페이스(타입의 안정성과 키 확인) • java.security.PublicKey • - 공개 키에 사용되는 인터페이스 • java.security.PrivateKey - 개인 키에 사용되는 인터페이스 Keys(3/3) • JDK 클래스 • public KeyPair(PublicKey publicKey, PrivateKey privateKey) • - 공개 키와 개인 키로 이루어지는 키 쌍 생성 • 메소드 : public PublicKey getPublic() • - 공개 키 리턴 public PrivateKey getPrivate() • - 개인 키 리턴
Public abstract void initialize(int strength, SecureRandom random) Public void initialize(int strength) Public abstract KeyPair genKeyPair() Key Generator(1/6) : 암호 키 생성( 암호키: 키 또는 키 쌍) • 암호 키 생성 단계 1.사용하기를 원하는 알고리즘에 대한 키 Generator 객체 획득 2. 키 genetator 초기화 3. 키 또는 키 쌍의 생성을 key generator에게 요청 java.security 클래스 java.security.KeyPairGenerator
javax.crypto 클래스 javax.crypto.KeyGenerator Public final void init(SecureRandom random)* Public final void init(int strength) Public final void init(int strength, SecureRandom random) Public final SecretKey generateKey( ) Key Generator(2/6)
Key Generator(3/6) • KeyPairGenerator 클래스 • : java.security.KeyPairGenerator-공개 키와 개인 키 쌍을 생성하고 KeyPair로 리턴. • Generator 객체를 getInstance() 메소드에 알고리즘의 종류를 명시하는 문자열 인수를 적용함으로 생성 • Ex) KeyPairGenerator kpg = KeyPairGenerator.getInstance(“ElGamal”) • -알고리즘을 발견하지 못할시 NoSuchAlgorithmException 동작 • Generator 초기화 메소드 public abstract void initialize(int strength, SecureRandom random) :보안강도(실제로 키가 차지하는 비트 수)와 난수로 초기화 public void initialize(int strength) :보안 강도로 초기화
Key Generator(4/6) • 키 생성 메소드 Public abstract KeyPair genKeyPair() • : 이전의 initialze()에서 명시된 강도와 랜덤 비트 소스를 사용하여 • key pair를 생성 • Ex) • KeyPairGenerator kpg = KeyPairGenerator.getInstance(“DSA”); • kpg.initialize(1024); • keyPair pair = kpg.genKeyPair();
Key Generator(5/6) • KeyGenerator 클래스 : 대칭 암호에서의 하나의 키 생성. 따라서 JCE는 jvax.crypto.KeyGenerator라는 랜덤한 하나의 키를 생성하는 클래스 포함 • Generator 객체 획득 • KeyGenerator kg = KeyGenerator.getInstance(“DES”) • 초기화 메소드 • Public final void init(SecureRandom random)* • : 난수 사용하여 KeyGenerator을 초기화 • Public final void init(int strength) • :보안 강도 사용 • Public final void init(int strength, SecureRandom random) • :보안 강도와 난수 사용
Key Generator(6/6) • 키 생성 메소드 • Public final SecretKey generateKey() • :새로운 랜덤 SecretKey를 생성 Ex) • KeyGenerator kg = KeyGenerator.getInstance (“DES”); • Kg.init(new SecureRandom()); • SecretKey key = kg.generateKey();
Algorithm-Specific Initialization(1/2) : Java.security.KeyPairGenerator와 javax.crypto.KeyGeneratorsms Algorithm-Specific Initialization의 개념을 지원 - 사용하는 알고리즘에 대한 정해진 파라메터를 사용가능 • Java.security.KeyPairGenerator는 Algorithm-Specific Initialization을 위한 하나의 메소드 포함 Public void initialize(AlgorithmParameterSpec params) throws • InvalidAlgorithmParameterException • : 만일 AlgorithmParameterSpec 객체가 인정되지 않는다면, 예외처리
Algorithm-Specific Initialization(2/2) • javax.crypto.KeyGenerator는 Algorithm-Specific Initialization을 위한 두 개의 메소드 포함 Public final void init(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException : 만일 AlgorithmParameterSpec 객체가 인정되지 않는다면, 예외처리 Public final void init(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException : 만일 AlgorithmParameterSpec 객체가 인정되지 않는다면, 예외처리
Class javax.crypto.spec.SecretKeySpec java.crypto.SecretKeyFactory javax.security.KeyFactory Key Translator(1/8) • Problem) 디스크에서의 키 저장, 네트워크에서의 키 전송 Solution) 바이트 열 단위로 키 저장 또는 전송 바이트 열과 vice versa로 Key 객체 변환 • 클래스를 사용하여 객체 변환
Key Translator(2/8) • SecretKeySpec : javax.crypto.spec.SecretKeySpec 클래스는 비밀 키의 바이트 열을 변환하는 가장 간단한 방법 . 두 개의 생성자를 가지고 있슴. • pubic SecretKeySpec(byte[] key, String algorithm) :제공된 바이트 열을을 사용하여 SecretKeySpec을 생성. Key에 알고리즘 제공. • pubic SecretKeySpec(byte[] key, int offset, int len, String algorithm) : 제공된 바이트 배열의 Offset에서 시작하는 len 바이트들을 사용하여 SecretKeySpec을 생성. 제공된 알고리즘 가짐. 예제) SecureRandom sr = new SecureRandom(); Byte[] keyByte = new byte[20]; Sr.nextBytes(keyBytes); SecretKey key = new SecretKeySpec (keyBytes, “HmacSHA1”);
Key Translator(3/8) • SecretKeyFactory 클래스 : java.crypto.SecretKeyFactory클래스는 getInstance() 함수를 이용하여 SecretKeyFactory를 생성. 두 개의 생성자 가짐. • pubic static final SecretKeyFactory getInstance(String algorithm) throws NoSuchAlgorithmException :주어진 알고리즘을 사용하여 새로운 SecretKeyFactory 생성 알고리즘 이름(예:DES)이 대칭 암호 알고리즘 이름과 일치해야함 • pubic static final SecretKeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException :알고리즘과 제공자를 사용하여, 새로운 SecretKeyFactory 생성 -SecretKeyFactory를 가지고 있다면, KeySpec와 SecretKey사에서의 key translate가 자유롭다
Key Translator(4/8) • From things to keys : SecretKey에서 KeySpec로의 translate는 SecretFactory의 generatorSecret() 함수를 사용한다 • pubic final SecretKey generateSecret(KeySpec keySpec) throws InvalidKeySepcException :keySpec의 정보를 사용하여, SecretKey 생성. 만일 KeySpec이 인정되지 않는다면, 예외처리 Ex) DES 키 생성 pubic SecretKey makeDESKey(byte[] input, int offset) throws NoSuchAlgorithmException, InvalidKeySepcException, InvalidKeySpecException { SecretKeyFactory desFactory = SecretKeyFactory.getInstance(“DES”); KeySpec spec = new DESKeySpec(input, offset); Return desFactory.generateSecret (spec); }
Key Translator(5/8) • makeDESKey() 함수의 단계 1.DES 키를 위한 키 요소의 획득. SecretKey.getInstance()를 사용 2.KeySpec은 제공된 바이트 열로부터 DES 키 데이터 표시 생성 3.KeySpec로부터의 SecretKey 생성. generateSecret()를 사용 • 예외사항 • getInstance()함수 • -NoSuchAlgorithmException • generatorSecret()함수 • -InvalidKeyException (정확하지 않은 키 길이 전달) • generatorSecret()함수 • -InvalidKeySpecException(KeySpec에서 불인정)
Key Translator(6/8) • From keys to things • : SecretFactory 는 SecretKey로부터 KeySpec 생성하는 방법 소유 • Public final KeySpec getKeySpec(SecretKey key, Class keySpec) throws • InvalidKeySpecException • :주어진 SecretKey로 부터 KeySpec 생성. keySpec 파라메터는 리턴되는 객체의 형태 결정 • Ex) • public byte[] makeBytesFromDESKey(SecretKey key) throws NoSuchAlgorithmException, InvalidKeySepcException { • SecretKeyFactory desFactory = SecretKeyFactory.getInstance(“DES”); • KeySpecSpec spec = (DESKeySpec) desFactory.getKey(key, DESKeySpec.class); • return spec.getKey();}
Key Translator(7/8) • KeyFactory 클래스 • : Java.security.KeyFactory 클래스는 SecretKeyFactory와 유사. • 공개키와 개인키에 적용 • Public static final KeyFactory getInstance(String algorithm) throws • NoSuchAlgrithmException • : 주어진 알고리즘을 사용하여 새로운 KeyFactory 생성에 사용 • : 알고리즘 이름은 비대칭 알고리즘 이름이거나 • 서명알고리즘(예:DSA)으로 해야함 • Public static final KeyFactory getInstance(String algorithm, String provider) throws NoSuchAlgrithmException, NoSuchProviderException • :제공된 제공자의 이름을 구현에 사용하여, 새로운 KeyFactory생성
Key Translator(8/8) • PublicKey 또는 Privatekey는 KeySpec으로 부터의 변환에 generatePublic()와 generatePrivate()메소드 사용 • Public final PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException :지정된 KeySpec을 PublicKey 생성에 사용 :만일 KeySpec이 KeyFactory에 인정되지 않으면, 예외처리 • Public final PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException :지정된 KeySpec을 개인키 생성에 사용 • KeyFactory는 공개키와 개인키를 동시에 조정하는 getKeySpec()을 갖는다 • Public final KeySpec getKeySpec(Key key, Class keySpec) throws InvalidKeySpecException :지정된 키로 부터 KeySpec 생성
- y - k - x x - y y x x x x m r m r m r m r • Notation - p : prime number - g: primitive mod p : public key : random number , , = g x mod p = g mod p m = y mod p = y mod p r m Key Agreement(1/7) : 두 개 이상의부분에 동일한 secret 값을 소유하게 하는 프로토콜 세션 키에서도 사용 • Diffie-Hellman -가장 널리 사용 됨 - 1976년경 발표 • 특징 : 비안전 채널 사용(예:인터넷) • 인증에는 사용하지 못함 직접적인 키 전송을 하지 않는다 사용자가 n일시, n-1 데이타 교환 필요
k x x x x m r m r 4.동일한 = g mod p m = y mod p 소유 = y mod p r m Key Agreement(2/7) 1. p와 g 선택. 가입자에게 배포 2. x 선택. y 계산 m m 3. y 로빈에게 전송 m Robin 2. x 선택. y 계산 r r Marian 3. y 마리안에게 전송 r
Key Agreement(3/7) • Javax.crypto.KeyAgreement • :Javax.crypto.KeyAgreement는 키 agreement 프로토콜을 캡슐화 • :SunJCE는 Diffie-Hellman이 기반이되된 KeyAgreemnet 제공 • KeyAgreement 객체 획득을 위하여, getInstance()메소드 사용 • Public static final KeyAgreement getInstance(String algorithm) throws • NosuchAlgorithmException • :주어진 알고리즘을 사용하여 새로운 KeyAgreement생성 • Public static final KeyAgreement getInstance(String algorithm, String provider) throws • NosuchAlgorithmException, NoSuchProviderException • :주어진 제공자의 이름으로, 새로운 KeyAgreement 생성
Key Agreement(4/7) • KeyAgreement 초기화 메소드 • Public final void init (Key key) throws InvalidKeyException • :제공된 키를 사용하여 KeyAgreement 초기화 • :올바른 키 형태가 아니라면 예외처리 발생 • Public final void init (Key key, SecureRandom random) throws • InvalidKeyException • :제공된 키와 난수로 KeyAgreement 초기화 • Public final void init (Key key, AlgorithmParameterSpec params) throws • InvalidKeyException, InvalidAlgorithmParameterException • :제공된 키와 AlgorithmParameterSpec으로 KeyAgreement 초기화 • Public final void init (Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException :제공된 키, AlgorithmParameterSpec, SecureRandom로KeyAgreement 초기화
Key Agreement(5/7) • Public final Key doPhase (Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException :공개 키 값 리턴. lastPhase는 키 agreement가 수행되기 시작한 마지막 단계 지시 • Secret 값 추출 • Public final byte[] generateSecret() throws IllegalStateException • :secret 값 리턴. KeyAgreement의 모든 단계 미실행시, 예외처리 • Public final init generateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException • :offset에서 시작한 배열에secret 값 write. 배열 길이 불충분시 예외처리 • Public final init generateSecret(String algorithm) throws InvalidKeyException, IllegalStateException, NoSuchAlgorithmException • :주어진 알고리즘으로 SecretKey에 대한 secret 값 리턴
Key Agreement(6/7) • SKIP (Simple Key Internet Protocol) Diffie-Hellman 사용 세션 키 사용 로컬 네트워크와 VPN(Virtual Private Key)에서 사용 키 크기에 따른 세가지 다른 베이스와 모듈 제공 • SKIP 베이스와 모듈 값을 위한 클래스를 정의 • 클래스 { • String // 16진법으로 모듈 값을 표시하기 위하여 스트링 정의 • 모듈 // BigInteger을 이용하여 모듈 값 생성 • 베이스 // 베이스 값 생성 • 저장 // DHParamterSpec에 모듈과 베이스 값 저장 • }
Key Agreement(7/7) 클라이언트 서 버 1.Key Pair 생성 1. Key Pair 생성 2. 명령 라인에 host IP와 포트 입력하여 네트워크 연결. 2. 네트워크 연결 wait 3. 공개 키 수신 공개 키 전송 3. 공개키 수신 4. KeyFactory를 이용 키 재구성 5. 자신의 공개키 전송 4. KeyFactory를 이용 키 재구성 5. Secret 값 계산 6. Secret 값 계산 6. Secret 값 출력 7. Secret 값 출력
목 차 1. Identity Key Management 의 정의 2. Key Holders - Principal - Identity - Signer - IdentityScope 4. KeyManager 구현
The Identity Key Management Paradigm • Identity Key Management 란? • JDK 1.1에서 java.security.Identity 클래스를 사용한 키관리 * JDK 1.2 에서는 Keystore-based Key Management 로 바뀜 • 구성 • Identity ; 공개키와 관련정보들을 포함 • Signer ; 공개키와 개인키, 그리고 관련정보들을 포함 • IdentityScope ; Identity 의 그룹을 표시하며 Identity 객체를 가짐
Identity Scope (Marian’s computer) Identity Scope (Merry Men) Signer (Marian) 공개키 개인키 기타 정보들 Identity (Will) 공개키 기타 정보들 Identity (Tuck) 공개키 기타 정보들 Identity (Sheriff) 공개키 기타 정보들 Identity (Robin) 공개키 기타 정보들 The Identity Key Management Paradigm Figure : Identity-based key management
Interface Principal MethodgetName() Class Constructor identity() identity(String name) identity(String name, IdentityScope scope) MethodgetPublicKey() setPulicKey(Publickey key) addCertificate(Certificate certificate) removeCertificate(Certificate certificate) Certificate[] getCertificates() Identity Signer Constructor Signer() Signer(String name) Signer(String name, IdentityScope scope) MethodgetPrivateKey() setKeyPair(KeyPair pari) IdentityScope Constructor identityScope() identityScope(String name) identityScope(String name, IdentityScope scope) MethodaddIdentity(Identity identity) removeIdentity(Identity identity) getIdentity(String name) getIdentity(PublicKey key) getIdentity(Principal principal) size() identites() Java.security For the Identity Key Management
Key Holder • Principal 인터페이스 • Identity 는 java.security.principal 인터페이스로 구현 • Principal 은 단순히 이름을 가져온다 • Method • public abstract String getName();
Key Holder • Identity 클래스 • 실제 세계의 실체들(사람이나 조직같은)을 표현 • 키의 소유자 확인 • 이름, 공개키, 공개키를 증명하는 증명서 포함 • Constructor • public Identity (String name); • public Identity (String name, IdentityScope scope) throws KeyManagementException;
Key Holder • Method ( 공개키 관리 ) • public PublicKey getPublicKey (); • public void setPublicKey (PublicKey key) throws KeyManagementException; ( 증명서 관리 ) • public void addCertificate (Certificate certificate) throws KeyManagementException; • public void removeCertificate (Certificate certificate) throws KeyManagementException; • public Certificate[] getCertificates ();
Key Holder • Signer 클래스 • 개인키 관리를 위해 추가로 제공되는 서브클래스 • Method • public PrivateKey getPrivateKey (); • public final void setKeyPair (KeyPair pair) throws InvalidParameterException KeyException;
Key Holder • IdentityScope • Identity의 그룹을 표시 • Identity의 객체 저장 • Identity의 Scope라는 개념을 제시 • IdentityScope 자체가 Identity로 다른 Scope에 속할수 있다 • 공개키, 인증서를 가질수 있다 • Identity 로 부터 상속 받은 클래스이므로 Signer 일수 없다
Key Holder • Method ( Identity 관리 ) • public abstract void addIdentity (Identity identity) throws KeyManagementException; • public abstract void removeIdentity (Identity identity) throws KeyManagementException; • public abstract int size (); • public abstract Enumeration identites (); • public abstract Identity getIdentity (String name); • public abstract Identity getIdentity (PublicKey key); • public Identity getIdentity (Principal principal);
KeyManager • Key 와 Identity 관리 클래스의 구현 • java KeyManager -c keyfile signer algorithm strength • java KeyManager -e keyfile idname outfile • java KeyManager -i keyfile infile • java KeyManager -r keyfile idname • java KeyManager -l keyfile
KeyManager • 구현된 함수들 • Constructor protected KeyManager(String name, KeyPair pair) { super(name); try { setPublicKey(pair.getPublic()); } catch (KeyManagementException kme) {} mPrivateKey = pair.getPrivate(); mIdentities = new Hashtable(); }
KeyManager • Name 의 Identity 획득 public synchronized Identity getIdentity(String name) { Enumeration e = mIdentities.elements(); while (e.hasMoreElements()) { Identity i = (Identity)e.nextElement(); if (i.getName().equals(name)) return i; } return null; } public Identity getIdentity(PublicKey key) { return (Identity)mIdentities.get(key); }
KeyManager • Identity 추가 public synchronized void addIdentity(Identity identity) throws KeyManagementException { if(mIdentities.contains(identity)) throw new KeyManagementException("This KeyManager already contains " + identity.getName() + "."); if(mIdentities.containsKey(identity.getPublicKey())) throw new KeyManagementException("This KeyManager already contains "+ identity.getName() + "'s key."); mIdentities.put(identity.getPublicKey(), identity); }
KeyManager • Identity 삭제 public synchronized void removeIdentity(Identity identity) throws KeyManagementException { PublicKey key = identity.getPublicKey(); if(mIdentities.containsKey(key)) mIdentities.remove(key); else throw new KeyManagementException("This KeyManager does not contain "+ identity.getName() + "."); }
KeyManager • 키 획득 public synchronized PublicKey getPublicKey(String name) { if(name.equals(getName())) return getPublicKey(); return getIdentity(name).getPublicKey(); } public PrivateKey getPrivateKey() { return mPrivateKey; }
KeyManager • Identity 추가 public void addIdentity(String name, PublicKey key) throws KeyManagementException { Identity i = new KeyManagerIdentity(name); i.setPublicKey(key); addIdentity(i); }
KeyManager • 인스턴스 획득 public static KeyManager getInstance(String file) throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); KeyManager km = (KeyManager)in.readObject(); in.close(); km.mKeyFile = file; return km; }
KeyManager • KeyManager 생성 public static KeyManager create(String file, String name, KeyPair pair) { KeyManager km = new KeyManager(name, pair); km.mKeyFile = file; return km; }
KeyManager • 저장 public synchronized void save() { try { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(mKeyFile)); out.writeObject(this); out.close(); } catch (Exception e) { System.out.println("KeyManager.save: " + e.toString()); } }
KeyManager • KeyMangerIdentity private static class KeyManagerIdentity extends Identity { public KeyManagerIdentity(String name) { super(name); } }