39
Chapter 9 Writing a Provider 데데데데데데 데데데 데 데 데 [email protected]

Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 [email protected]

Embed Size (px)

Citation preview

Page 1: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

Chapter 9

Writing a Provider

데이타베이스 실험실

강 민 석[email protected]

Page 2: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 2 Kang Minsuk

Contents

Getting Start

Adding the ElGamal Classes

ElGamal

Generating Keys

Signature

Cipher

Page 3: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 3 Kang Minsuk

Provider

ProvidersProgram

MessageDigestSecurity2. MD5 를 구현한 message digest 객체

요구

5. 여기 instance 가 있습니다.

3. 누가 MD5 message digest

class 를 가지고 있나 ?

4. sun.security.provider.

MD5 class 입니다 .

1.MD5 알고리즘을 구현한 instance 를 주세요

6. 여기 있습니다.

MessageDigest.getInstance(“MD5”)

Page 4: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 4 Kang Minsuk

Getting Started(Algorithm Names and Implementations)

알고리즘 이름을 클래스 이름으로 mapping

DES/CBC/PKCS5Padding : oreilly.jonathan.crypto.CBCWrapper

DES/CFB/NoPadding : oreilly.jonathan.crypto.CFBWrapper

Cipher.DES/CBC/PKCS5Padding : oreilly.jonathan.crypto.CBCWrapper

Cipher.DES/CFB/NoPadding : oreilly.jonathan.crypto.CFBWrapper

Cryptographic provider 여러 종류의 알고리즘을 포함 할 수 있음

key pair generation, signatures, cipers,.. 알고리즘 이름은 type and name 으로 만들어짐

Page 5: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 5 Kang Minsuk

A Simple Provider

Subclass 생성 CBCWrapper, CFBWrapper classes 에 대한 mapping 을 포함 하는

subclass 생성 oreilly.jonathan.security.provider

package oreilly.jonathan.crypto;import java.security.*;public class Provider extends java.security.Provider { public Provider() { super ("Jonathan", 1.2, "Jonathan's Cryptography Provider"); put("Cipher.DES/CBC/PKCS5Padding", "oreilly.jonathan.crypto.CBCWrapper"); put("Cipher.DES/CFB/Nopadding",

"oreilly.jonathan.crypto.CFBWrapper"); } }

Provider name 을 받아들이는getInstance() 메소드에서 이용됨

Page 6: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 6 Kang Minsuk

An Algorithm by Any Other Name

다른 알고리즘 name 으로 같은 구현을 return sun provider 에서 다음은 같은 message digest 구현을 얻음

MessageDigest one = MessageDigest.getInstance("SHA-1");MessageDigest two = MessageDigest.getInstance("SHA");

Class 가 8 bit CFB 모드이기 때문에 CFBWrapper 와 연결하기 위한 “ DES/CFB8/NoPadding” 을 원할 경우

Put(“Alg.Alias.Cipher.DES/CFB8/NoPadding” , “DES/CFB/NoPadding”);

우리의 provider 에서 다음은 같은 결과를 초래

Cipher one = Cipher.getInstance("DES/CFB8/NoPadding");Cipher two = Cipher.getInstance("DES/CFB/NoPadding");

Page 7: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 7 Kang Minsuk

Installing the Provider

security.provider.1 = sun.security.provider.Sunsecurity.provider.2 = com.sun.crypto.provider.SunJCEsecurity.provider.3 = oreilly.jonathan.crypto.Providersecurity.provider.4 = cryptix.security.Cryptixsecurity.provider.5 = iaik.security.provider.IAIK

~/Lib/security/java.security 파일 수정

Application 에서 runtime 시 Jonathan Provider 를 추가하는 방법

java.security.Provider p = new oreilly.jonathan.security.Provider();Security.addProvider(p);

Page 8: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 8 Kang Minsuk

Adding the ElGamal Classes

Jonathan provider 의 class

oreilly.jonathan.crypto.ElGamalKeyPairGenerator oreilly.jonathan.crypto.ElgamalSignature oreilly.jonathan.crypto.ElGamalCipher

Adding the Provider(ElGamal) Classespackage oreilly.jonathan.crypto;import java.security.*;public class Provider extends java.security.Provider { public Provider( ) { super("Jonathan", 1.2, "Jonathan's Cryptography Provider");

put("KeyPairGenerator.ElGamal", "oreilly.jonathan.crypto.ElGamalKeyPairGenerator");

Page 9: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 9 Kang Minsuk

put("Cipher.ElGamal",

"oreilly.jonathan.crypto.ElGamalCipher");

put("Signature.ElGamal",

"oreilly.jonathan.crypto.ElGamalSignature");

put("Cipher.DES/CBC/PKCS5Padding",

"oreilly.jonathan.crypto.CBCWrapper");

put("Cipher.DES/CFB/NoPadding",

"oreilly.jonathan.crypto.CFBWrapper");

put("Alg.Alias.Cipher.DES/CFB8/NoPadding",

"DES/CFB/NoPadding");

}

}

Cont’d

Page 10: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 10 Kang Minsuk

ElGamal 알고리즘의 이용

ciphertext plaintextplaintextcipher cipher

Encryption Decryption

ElGamal 알고리즘 이용

Page 11: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 11 Kang Minsuk

ElGamal(Key pair Generation)

Random prime p 를 생성 (modulus 라 불림 ) p size 는 key size 와 같다 . Ex. : 2048 bit key has a P that is 2048 bit

Random number g, x 선택 g, x < p

x is private key

y = gx mod p 계산 p, g, y are public key

Page 12: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 12 Kang Minsuk

Signature 생성 단계

p - 1 과 서로소인 난수 k 를 선택 k 와 p-1 은 1 을 제외한 공통인수가 없음

a 와 b 를 계산

signature 확인

a = gk mod p b = ((m-xa) / k) mod (p-1)* m 은 메시지이고 a,b 는 signature

yaab mod p = gm mod p 를 검사

K 는 공개 되서는 안됨

Page 13: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 13 Kang Minsuk

Cont’d

공개키 : y =3, g =2, p = 11

예 ) p=11, g =2 , x = 8 라면y = gx mod p = 28 mod 11 = 3

인증 (signature)

난수 k = 9 를 선택 , m = 5 라 할 때 a = gk mod p = 29 mod 11 = 6b = ((m-xa) / k) mod (p-1) = ((5-8*6) / 9) mod 10 = 3

yaab mod 11 = gm mod p

3663 mod 11 = 9, 25 mod 11 = 9

인증 (signature) 확인

암호화 (Cipher)

난수 k = 9 를 선택 , m = 5

a= gk mod p = 29 mod 11 = 6 b= yk m mod p = 39 * 5 mod 11 = 9

복호화

m = ( b / ax ) mod P

Page 14: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 14 Kang Minsuk

Cipher

p - 1 과 서로소인 난수 k 를 선택 암호문 a 와 b 를 계산

복호 (decrypt) 를 위해 m = ( b / ax ) mod P 를 계산

( b / ax ) mod p = ((yk * m) / gkx ) mod p

= ((gkx * m) / gkx ) mod p

= m mod p

a = gk mod p b = yk * m mod p

* m 은 평문 , 숫자 a 와 b 는 암호문 (modulus p 보다 2 배 큼 )

Page 15: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 15 Kang Minsuk

Generating Keys(key Classes)

ElGamal 의 공개키 (p, g) 생성package oreilly.jonathan.crypto;import java.math.BigInteger; // 모든 수학적인 계산을 수행함import java.security.*;

public class ElGamalKey implements Key { private BigInteger mP, mG; protected ElGamalKey (BigInteger g, BigInteger p) mG=g; mP=p; } protected BigInteger getG( ) { return mG ; } protected BigInteger getP( ) { return mP; }

public String getAlgorithm( ) { return "ElGamal"; } public String getFormat( ) { return "NONE"; } public byte[] getEncoded( ) { return null; } }

공개키 p, g, y개인키 x

Page 16: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 16 Kang Minsuk

Cont’d

공개키 y 를 포함하는 Public key class 생성package oreilly.jonathan.crypto ; import java.math.BigInteger ;import java.security.* ;

public class ElGamalPublicKey extends ElGamalKey implements PublicKey { private BigInteger mY;

protected ElGamalPublicKey(BigInteger y, BigInteger g, BigInteger p) { super(g, p); mY=y; }

protected BigInteger getY() return mY; }

Page 17: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 17 Kang Minsuk

Cont’d

ElGamalPrivateKey x 생성

packgae oreilly.jonathan.crypto;import java.math.BigInteger;import java.security.*;

public class ElGamalPrivateKey extends ElGamalKey implements PrivateKey { private BigInteger mX ;

protected ElGamalPrivateKey(BigInteger x, BigInteger g, BigInteger p) { super(g, p) ; mX= x ; }

protected BigInteger getX() return mX; }

Page 18: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 18 Kang Minsuk

ElGamal Key Pair Generator

package oreilly.jonathan.crypto;

import java.math.BigInteger;import java.security.*;

public class ElGamalKeyPairGenerator extends KeyPairGeneratorSpi { private int mStrength = 0; private SecureRandom mSecureRandom = null;

// Strength is interpreted as the bit length of p. public void initialize(int strength, SecureRandom random) { mStrength=strength; mSecureRandom=random; }

Strength 와 SecureRandom 의 측정으로 초기화됨

Page 19: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 19 Kang Minsuk

public KeyPair generateKeyPair( ) { if (mSecureRandom==null) { /* default 처리 */ mStrength=1024; mSecureRandom=new SecureRandom( ); }

BigInteger p=new BigInteger (mStrength, 16, mSecureRandom); BigInteger g=new BigInteger (mStrength, -1, mSecureRandom); BigInteger x=new BigInteger (mStrength, -1, mSecureRandom); BigInteger y=g.modPow(x, p); // y 값 계산

ElGamalPublicKey publicKey = new ElGamalPublicKey(y, g, p); ElGamalPrivateKey privateKey = new ElGamalPrivateKey(x, g, p); return new KeyPair(publicKey, privateKey); } }

Cont’d

소수가 될 확률 : 1- 0.516

Page 20: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 20 Kang Minsuk

package oreilly.jonathan.crypto ;

import java.io.ByteArrayOutputStream;

import java.math.BigInteger;

import java.sercurity.*;

public class ElGamalSignature

extends SignatureSpi {

protected ElGamalKey mKey ; /* 나중에 서명 값을 생성 또는 확인할 key 저장 */

protected ByteArrayOutputStream mOut; /* data 저장 - 서명 값 생성 또는 확인 시 이용함 */

protected static BigInteger kOne = BigInteger.valueOf(1) ;

Signature

ElGamal signature class 를 구현하기 위하여 signature 의 SPI 를 구현함

Page 21: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 21 Kang Minsuk

protected void engineInitVerify(PublicKey key) throws InvalidKeyException { if ( !(key instanceof ElGamalPublicKey)) throw new InvalidKeyException(”I didn'd get an ElGamalPublicKey.")"; mKey = (ElGamalKey)key; mOut = new ByteArrayOutputStream( ); }

protected void engineInitSign(PrivateKey key) throws InvalidKeyException { if ( !(key instanceof ElGamaPrivateKey)) throw new InvalidKeyException("I didn't get an ElGamalPrivateKey."); mKey = (ElGamalKey)key; mOut = new ByteArrayOutputStream( ); }

Cont’d서명의 initVerify() 호출 시

이 메소드가 호출됨

서명의 initsign( ) 호출 시이 메소드가 호출됨

Page 22: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 22 Kang Minsuk

//signature’s update( ) 메소드 호출시 호출됨protected void engineUpdate(byte b) throws SignatureException { mOut.write(b) ; }

protected void engineUpdate(byte[] b, int off, int len) throws SignatureException { mOut.write(b, off, len); } //Signature API 에 있는 sign() 와 동등한 SPIprotected byte[] engineSign() throws SignatureException {

BigInteger x = ((ElGamalPrivateKey)mKey).getX();BigInteger g = mKey.getG();BigInteger p = mKey.getP();BigInteger pminusone = p.subtract(kOne); // p-1 값 계산

Cont’d

ByteArrayOutputStream 에 input data 기록

Page 23: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 23 Kang Minsuk

BigInteger k ; // 랜덤한 k 값 선택 do { k = new BigInteger(p.bitLength() - 1, new SecureRamdom()); } while (k.gcd(pminusone).equals(kOne) == false); // ByteArrayOutputStream 에 저장된 모든 byte 를 BingInterger m 으로 변환 BigInteger m = new BigInteger(1, mOut.toByteArray());

// 서명이 a, b 의 계산에 의해 표현 BigInteger a = g.modPow(k, p); BigInteger top = m.subtract(x.multiply(a)).mod(pminusone); BigInteger b = top.multiply( k.modPow(kOne.negate( ) , pminusone)).mod(pminusone);

Cont’d

Page 24: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 24 Kang Minsuk

int modulusLength = (p.bitLength() + 7) /8; byte[] signature = new byte[modulusLength * 2]; byte[] aBytes = getBytes(a); int aLength = aBytes.length; byte[] bBytes = getBytes(b); int bLength = bBytes.length; System.arraycopy(aBytes, 0, signature, modulusLength - aLength, aLength); System.arraycopy(bBytes, 0, signature, modulusLength * 2 - bLength, bLength); return signature ; }

protected boolean engineVerify(byte[] sigBytes) throws SignatureException { BigInteger y = ((ElGamalPublicKey).getY(); Biginteger g = mKey.getG(); BigInteger p = mKey.getP();

Modulus p 의 두배 만큼 배열을 할당하고 a, b 값을 저장

공개키로부터 매개변수 추출

Page 25: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 25 Kang Minsuk

// a, b 를 추출하기 위하여 BigInteger 생성 int modulusLength = (p.bitLength() + 7) / 8 ; byte[] aBytes = new byte[modulusLength] ; byte[] bBytes = new byte[modulusLength] ; System.arraycopy(sigBytes, 0, aBytes, 0, modulusLength) ; System.arraycopy(sigBytes, modulusLength, bBytes, 0, moduluslength) ; BigInteger a = new BigInteger(1, aBytes) ; BigInteger b = new BigInteger(1, bBytes) ; BigInteger first = y.modPow(a,p).multiply(a.modPow(b, p)).mod(p) ;

// 서명의 정확성 검사 루틴 BigInterger m = new BigInteger(1, mOut.toByteArray()) ; BigInteger second = g.modPow(m,p) ;

return first.equals(second) ; }

Cont’d

Page 26: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 26 Kang Minsuk

protected byte[] getBytes(BigInteger big) { byte[] bigBytes = big.toByteArray( ); if ((big.bitLength( ) % 8) != 0) { return bigBytes ; } else { byte[] smallerBytes = new byte[big.bitLength() / 8] ; System.arraycopy(bigBytes, 1, smallerByters, 0, smallerByters.length) ; return smallerBytes ; } }

/*ElGamalSignature 는 parameter 를 이용하지 않음 . 하지만 이것을 정의하지 않으면 SignatureSpi 의 subclass 를 생성할 수 없음 */protected void engineSetParameter ( String param, Object value) throws InvalidParameterException { } protected object engineGetParameter(String param) throws InvalidParameterException { return null ; } }

Cont’dBigInteger 값을 갖는

byte 배열 return

Page 27: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 27 Kang Minsuk

Cipher

ciphertext

Decrypted plaintext

plaintext

ElGamalDecryption

ElGamalEncryption

0 00

암호화 Key(p) size 의 2 배

Public Key

Public Key

Page 28: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 28 Kang Minsuk

package oreilly.jonathan.crypto;import java.math.BigInteger;import java.security.* ;import java.security.spec.* ;import javax.crypto.* ;

public class ElGamalCipher extends BlockCipher { protected int mState ; protected Key mKey ; protected SecureRandom mSecureRandom ; protected int mPlainBlockSize ; protected int mCihperBlockSize ;

Cipher

Java.crypto.CipherSpi 를 확장한 class.oreilly.jonathan.crypto packag 에 있음

초기화 될때 ElGamalCipher 에게 전달됨

Page 29: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 29 Kang Minsuk

Cont’d protected void engineSetMode(String mode) throws NoSuchAlgorithmException { throw new NoSuchAlgorithmException("ElGamalCipher supports no modes.") ; } // padding 과 no mode 를 지원하기 때문에 engineSetMode 와 engineSetPadding 는 호출 시 바로 예외 처리로 감 // protected void engineSetPadding(String padding) throws NoSuchPaddingException { throw new NoSuchPaddingException("ElGamalCipher supports no padding.") ; }

protected int engineGetBlockSize( ) { // cipher 의 상태를 근거로한 if ( mState == Cipher.DECRYPT_MODE ) // 적당한 크기를 return return mCipherBlockSize ; else return mPlainBlockSize ; }

Page 30: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 30 Kang Minsuk

ciphertext

Decrypted plaintext

plaintext

ElGamalDecryption

ElGamalEncryption

0 00

암호화 Key(p) size 의 2 배

Public Key

Public Key

ElGamalCipher 에서의 Block handling

Page 31: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 31 Kang Minsuk

protected int engineGetOutputSize(int inLen) { int inBlocks ; int outLength ; if (mState == Cipher.ENCRYPT_MODE) { inBlocks = ( inLen + getBufferedDataLength() + mPlainBlockSize - 1) / mPlainBlockSize ; outLength = inBlocks * mCipherBlocksize ; } else { inBlocks = (inLen + getBufferedDataLengrh() + mCipherBlockSize - 1) / mCipherBlockSize ; outLength = inBlocks * mPlainBlockSize ; } return outLength ; } protected byte[] engineGetIV( ) { return null ; } //ElGamal 은 ECB mode 에서만 작동 하기 때문에 null 값을 return

Cont’d

Output buffer size 의 계산

Page 32: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 32 Kang Minsuk

// block 크기를 계산하기 위하여 calculateBlockSize() 메소드 이용 protected void engineInit ( int opmode, Key key, SecureRandom random) throws InvalidkeyException { if ( opmode == Cipher.ENCRYPT_MODE ) if ( !(key instanceof ElGamalPublicKey)) throw new InvalidkeyException("I didn't get an ElGamalPublicKey."); else if (opmode == Cipher.DECRYPT_MODE) if ( !(key instanceof ElGamalPrivatekey)) throw new InvalidKeyException("I didn't get an ElGamalPrivatekey.") ; else throw new IllegalArgumentException("Bad mode: " + opmode); // key 값이 정확한지 검사 mState = opmode; mKey = key; mSecureRandom = random ; calculateBlockSizes(key) ; } // block 크기를 계산하기

Cont’d

Page 33: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 33 Kang Minsuk

protected void engineInti(int opmode, Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgoritmParameterException { engineInit(opmode, key, random); // 이전에 오버로드 된 버전만 호출 } protected void calculateBlockSizes(Key key) { int modulusLength = (( ElGamalKey)key).getP().bitLength() ; mPlainBlockSize = (modulusLength - 1) / 8 ; mCipherBlockSize = ((modulusLength + 7) / 8) * 2 ; }// 암호 초기화 이전에 평문과 암호문의 크기 계산

Cont’d

Page 34: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 34 Kang Minsuk

protected int engineTransformBlock(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset ) throws ShortBufferException { If ( mState == Cipher.ENCRYPT_MODE) return encryptBlock(input, inputOffset, inputLength, output, outputOffset); else if (mState == Cipher.DECRYPT_MODE) return decryptBlock ( input, inputOffset, inputLength, output, outputOffset ) ; return 0 ; } // no padding 을 지원하기 때문에 두 메소드는 같은 역할

protected int engineTransformBlockFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset ) throws ShortBufferException { If ( inputLength == 0 ) return 0 ; return engineTransformBlock(input, inputOffset, InputLength, output, outputOffset) ; }

Cont’d

Page 35: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 35 Kang Minsuk

protected int encryptBlock ( byte[] in, int inOff, int inLen, byte[] out, int outOff) { byte[] messageBytes = new byte[mPlainBlockSize] ; int inputLength = Math.min(mPlainBlockSize, inLen) ; System.arraycopy(in, inOff, messageBytes, 0, inputLength) ; BigInteger m = new BigInteger(1, messageBytes) ;

ElGamalPublicKey key = (ElGamalPublicKey)mKey ; BigInteger p = key.getP() ; BigInteger one = BigInteger.valueOf(1) ; BigInteger pminusone = p.subtract(one) ; BigInteger k ; // k 생성 do { k = new BigInteger ( p.bitLength() - 1, mSecureRandom) ; } while (k.gcd(pminusone).equals(one) == false) ;

Cont’dInput byte 로부터

message value 생성

Page 36: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 36 Kang Minsuk

BigInteger a = key.getG().modPow(k, p); //a, b 계산 BigInteger b = key.getY().modPow(k, p).multiply(m).mod(p) ;

byte[] aBytes = getBytes(a) ; // a, b 를 output buffer 에 복사 byte[] bBytes = getBytes(b) ;

System.arraycopy(aBytes, 0, out, outOff + mCipherBlockSize / 2

- aBytes.length, aBytes.length) ;

System.arraycopy(bBytes, 0, out, outOff + mCipherBlockSize

- bBytes.length, bBytes.length);

return mCipherBlockSize ; // encryptBlock() 은 쓰여진 암호문 byte 의 // 수를 return

}

Cont’d

Page 37: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 37 Kang Minsuk

protected int decryptBlock(byte[] in, int inOff, int inLen, // 복호처리 byte[] out, int outOff ) { //pull out our key ElGamalPrivateKey key = (ElGamalPrivateKey)mKey ; BigInteger p = key.getP() ;

// Extract a and b byte[] aBytes = new byte[mCipherBlockSize / 2] ; System.arraycopy(in, inOff, aBytes, 0, mCipherBlockSize / 2) ; byte[] bBytes = new byte[mCipherBlockSize / 2 ] ; System.arraycopy(in, inOff + mCipherBlockSize / 2, bBytes, 0, mCipherBlockSize /2) ; BigInteger a = new BigInteger(1, aBytes) ; BigInteger b = new BigInteger(1, bBytes) ; // 메시지 m 계산 BigInteger m = b.multiply(a.modPow(key.getX().negate(), p)).mod(p) ;

Cont’d

Page 38: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 38 Kang Minsuk

byte[ ] messageBytes = getBytes(m) ; int gatedLength = Math.min(messageBytes.length, mPlainBlockSize) ; System.arraycopy(messageBytes, 0, out,

outOff + mPlainBlockSize - gatedLength, gatedlength ) ; return mPlainBlockSize ; // 메시지 값의 byte 를 output buffer 에 복사 } // 복호된 byte 의 수를 return protected byte[ ] getBytes( BigInteger big ) { byte[ ] bigBytes = big.toByteArray(); if (( big.bitLength() % 8 ) !=0 ) { return bigBytes ; } else { byte[ ] smallerBytes = new byte[big.bitLenth() / 8 ] ; System.arraycopy(bigBytes, 1, smallerBytes, 0, smallerBytes.length ) ; return smallerBytes ; } }}

Cont’d

Page 39: Chapter 9 Writing a Provider 데이타베이스 실험실 강 민 석 kangms@dblab.hannam.ac.kr

DB Lab. 39 Kang Minsuk

추후 연구

Padding 기법 구현 복호된 평문이 이전의 원문과 같아 지도록

예외처리를 향상 시켜라 .

encryptBlcok( ) method

decryptBlock( ) method