feat: 암복구화 및 단방향 암호화 유틸 추가 #5
Merged
dhji
merged 1 commits from feature/encrypt
into develop
8 months ago
8 changed files with 5283 additions and 5 deletions
@ -1,6 +1,6 @@ |
|||||||
|
|
||||||
|
|
||||||
dependencies { |
dependencies { |
||||||
|
implementation 'org.springframework.boot:spring-boot-starter' |
||||||
} |
} |
||||||
|
|
||||||
|
@ -0,0 +1,87 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j; |
||||||
|
|
||||||
|
import javax.crypto.Cipher; |
||||||
|
import javax.crypto.spec.IvParameterSpec; |
||||||
|
import javax.crypto.spec.SecretKeySpec; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Base64; |
||||||
|
|
||||||
|
@Slf4j |
||||||
|
public class EncryptUtil { |
||||||
|
|
||||||
|
// 16byte
|
||||||
|
private static String ENCRYPT_KEY = "__DEFAULT__KEY__"; |
||||||
|
private static String ENCRYPT_IV = "DEFAULT_IV_VALUE"; |
||||||
|
|
||||||
|
public static void setEncryptKey(String encryptKey) { |
||||||
|
ENCRYPT_KEY = encryptKey; |
||||||
|
} |
||||||
|
|
||||||
|
public static void setEncryptIv(String encryptIv) { |
||||||
|
ENCRYPT_IV = encryptIv; |
||||||
|
} |
||||||
|
|
||||||
|
public static String encrypt(String value) { |
||||||
|
return encrypt(ENCRYPT_KEY, ENCRYPT_IV, value); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String encrypted) { |
||||||
|
return decrypt(ENCRYPT_KEY, ENCRYPT_IV, encrypted); |
||||||
|
} |
||||||
|
|
||||||
|
// 암호화
|
||||||
|
public static String encrypt(String key, String initVector, String value) { |
||||||
|
log.info("encrypt() key: {}, initVector: {}, value: {}", key, initVector, value); |
||||||
|
try { |
||||||
|
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8)); |
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); |
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv); |
||||||
|
// cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
|
||||||
|
byte[] encrypted = cipher.doFinal(value.getBytes()); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
String encodedString = encoder.encodeToString(encrypted); |
||||||
|
log.debug("encrypted string: {}", encodedString); |
||||||
|
return encodedString; |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("encrypt() Exception: {}", e.getMessage()); |
||||||
|
} |
||||||
|
return value; |
||||||
|
} |
||||||
|
|
||||||
|
// 복호화
|
||||||
|
public static String decrypt(String key, String initVector, String encrypted) { |
||||||
|
log.info("decrypt() key: {}, initVector: {}, encrypted: {}", key, initVector, encrypted); |
||||||
|
try { |
||||||
|
|
||||||
|
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8)); |
||||||
|
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); |
||||||
|
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); |
||||||
|
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); |
||||||
|
//cipher.init(Cipher.DECRYPT_MODE, skeySpec);
|
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] original = cipher.doFinal(decoder.decode(encrypted)); |
||||||
|
|
||||||
|
return new String(original); |
||||||
|
} catch (Exception e) { |
||||||
|
log.error("decrypt() Exception: {}", e.getMessage()); |
||||||
|
} |
||||||
|
return encrypted; |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
String key = "1234567890123456"; |
||||||
|
String initVector = "1234567890123456"; |
||||||
|
String test = "test"; |
||||||
|
|
||||||
|
// WkaOhqSK03Z1pSuPOdc03w==
|
||||||
|
// WkaOhqSK03Z1pSuPOdc03w==
|
||||||
|
String encrypted = encrypt(test); |
||||||
|
log.info("encrypted: {}", encrypted); |
||||||
|
String decrypted = decrypt(encrypted); |
||||||
|
log.info("decrypted: {}", decrypted); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
package kr.co.palnet.kac.util; |
||||||
|
|
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_CBC; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_CTR; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SEED_ECB; |
||||||
|
import kr.co.palnet.kac.util.kisa.KISA_SHA256; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Base64; |
||||||
|
|
||||||
|
public class KisaEncryptUtil { |
||||||
|
// 사용자가 지정하는 입력 키 (16 bytes)
|
||||||
|
private final static String PBSZ_USER_KEY = "PBSZ_USER_KEY___"; // 16 bytes
|
||||||
|
// 사용자가 지정하는 초기화 벡트 (16 bytes)
|
||||||
|
private final static String PBSZ_VECTOR = "PBSZ_INIT_VECTOR"; // 16 bytes
|
||||||
|
public static class EcbEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] ecbEncBytes = KISA_SEED_ECB.SEED_ECB_Encrypt(PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), value.getBytes(StandardCharsets.UTF_8), 0, value.getBytes(StandardCharsets.UTF_8).length); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] ecbEncode = encoder.encode(ecbEncBytes); |
||||||
|
return new String(ecbEncode); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] ecbDecoder = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
byte[] ecbDecBytes = KISA_SEED_ECB.SEED_ECB_Decrypt(PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), ecbDecoder, 0, ecbDecoder.length); |
||||||
|
return new String(ecbDecBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class CbcEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] ecbEncBytes = KISA_SEED_CBC.SEED_CBC_Encrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
value.getBytes(StandardCharsets.UTF_8), |
||||||
|
0, |
||||||
|
value.getBytes(StandardCharsets.UTF_8).length |
||||||
|
); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] ecbEncode = encoder.encode(ecbEncBytes); |
||||||
|
return new String(ecbEncode); |
||||||
|
} |
||||||
|
|
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] ecbDecoder = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
byte[] ecbDecBytes = KISA_SEED_CBC.SEED_CBC_Decrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
ecbDecoder, |
||||||
|
0, |
||||||
|
ecbDecoder.length |
||||||
|
); |
||||||
|
return new String(ecbDecBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class CtrEncrypt { |
||||||
|
|
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] encBytes = KISA_SEED_CTR.SEED_CTR_Encrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
value.getBytes(StandardCharsets.UTF_8), |
||||||
|
0, |
||||||
|
value.getBytes(StandardCharsets.UTF_8).length |
||||||
|
); |
||||||
|
Base64.Encoder encoder = Base64.getEncoder(); |
||||||
|
byte[] encodeBytes = encoder.encode(encBytes); |
||||||
|
return new String(encodeBytes); |
||||||
|
} |
||||||
|
public static String decrypt(String value) { |
||||||
|
Base64.Decoder decoder = Base64.getDecoder(); |
||||||
|
byte[] decodeBytes = decoder.decode(value.getBytes(StandardCharsets.UTF_8)); |
||||||
|
|
||||||
|
byte[] decBytes = KISA_SEED_CTR.SEED_CTR_Decrypt( |
||||||
|
PBSZ_USER_KEY.getBytes(StandardCharsets.UTF_8), |
||||||
|
PBSZ_VECTOR.getBytes(StandardCharsets.UTF_8), |
||||||
|
decodeBytes, |
||||||
|
0, |
||||||
|
decodeBytes.length |
||||||
|
); |
||||||
|
return new String(decBytes); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class ShaEncrypt { |
||||||
|
public static String encrypt(String value) { |
||||||
|
byte[] bytes = value.getBytes(StandardCharsets.UTF_8); |
||||||
|
byte[] pszDigest = new byte[32]; |
||||||
|
KISA_SHA256.SHA256_Encrpyt(bytes, bytes.length, pszDigest); |
||||||
|
StringBuffer encrypted = new StringBuffer(); |
||||||
|
for (int i = 0; i < 32; i++) { |
||||||
|
encrypted.append(String.format("%02x", pszDigest[i])); |
||||||
|
} |
||||||
|
return encrypted.toString(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
String message = "this is message!!@#!$^#$%^&@#$~!@ 메시지 입니다.___+_+)(_)("; |
||||||
|
System.out.println("message = " + message); |
||||||
|
System.out.println("=============== ECB ================="); |
||||||
|
String ecbEncStr = EcbEncrypt.encrypt(message); |
||||||
|
System.out.println("ecbEncStr = " + ecbEncStr); |
||||||
|
String ecbDecStr = EcbEncrypt.decrypt(ecbEncStr); |
||||||
|
System.out.println("ecbDecStr = " + ecbDecStr); |
||||||
|
|
||||||
|
System.out.println("=============== CBC ================="); |
||||||
|
String cbcEncStr = CbcEncrypt.encrypt(message); |
||||||
|
System.out.println("cbcEncStr = " + cbcEncStr); |
||||||
|
String cbcDncStr = CbcEncrypt.decrypt(cbcEncStr); |
||||||
|
System.out.println("cbcDncStr = " + cbcDncStr); |
||||||
|
|
||||||
|
System.out.println("=============== CTR ================="); |
||||||
|
String ctrEncStr = CtrEncrypt.encrypt(message); |
||||||
|
System.out.println("ctrEncStr = " + ctrEncStr); |
||||||
|
String ctrDncStr = CtrEncrypt.decrypt(ctrEncStr); |
||||||
|
System.out.println("ctrDncStr = " + ctrDncStr); |
||||||
|
|
||||||
|
System.out.println("=============== SHA ================="); |
||||||
|
String shaEncStr = ShaEncrypt.encrypt(message); |
||||||
|
System.out.println("shaEncStr = " + shaEncStr); |
||||||
|
} |
||||||
|
} |
@ -1,4 +0,0 @@ |
|||||||
package kr.co.palnet.kac.util; |
|
||||||
|
|
||||||
public class Sample { |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,453 @@ |
|||||||
|
package kr.co.palnet.kac.util.kisa; |
||||||
|
|
||||||
|
/** |
||||||
|
@file KISA_SHA256.java |
||||||
|
@brief SHA256 암호 알고리즘 |
||||||
|
@author Copyright (c) 2013 by KISA |
||||||
|
@remarks http://seed.kisa.or.kr/
|
||||||
|
*/ |
||||||
|
|
||||||
|
public class KISA_SHA256 { |
||||||
|
|
||||||
|
// DEFAULT : JAVA = BIG_ENDIAN
|
||||||
|
private static int ENDIAN = Common.BIG_ENDIAN; |
||||||
|
|
||||||
|
private static final int SHA256_DIGEST_BLOCKLEN = 64; |
||||||
|
private static final int SHA256_DIGEST_VALUELEN = 32; |
||||||
|
|
||||||
|
private static final int SHA256_K[] = |
||||||
|
{ |
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, |
||||||
|
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, |
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, |
||||||
|
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, |
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, |
||||||
|
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, |
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, |
||||||
|
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, |
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, |
||||||
|
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, |
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
private static final int ROTL_ULONG(int x, int n) { |
||||||
|
return (x << n) | Common.URShift(x, 32 - n); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int ROTR_ULONG(int x, int n) { |
||||||
|
return Common.URShift(x, n) | (x << (32 - (n))); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int ENDIAN_REVERSE_ULONG(int dwS) { |
||||||
|
return ( (ROTL_ULONG((dwS), 8) & 0x00ff00ff) | (ROTL_ULONG((dwS), 24) & 0xff00ff00) ); |
||||||
|
} |
||||||
|
|
||||||
|
private static final void BIG_D2B(int D, byte[] B, int B_offset) { |
||||||
|
Common.int_to_byte_unit(B, B_offset, D, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int RR(int x, int n) { return ROTR_ULONG(x, n); } |
||||||
|
private static final int SS(int x, int n) { return Common.URShift(x, n); } |
||||||
|
|
||||||
|
private static final int Ch(int x, int y, int z) { return ((x & y) ^ ((~x) & z)); } |
||||||
|
private static final int Maj(int x, int y, int z) { return ((x & y) ^ (x & z) ^ (y & z)); } |
||||||
|
private static final int Sigma0(int x) { return (RR(x, 2) ^ RR(x, 13) ^ RR(x, 22)); } |
||||||
|
private static final int Sigma1(int x) { return (RR(x, 6) ^ RR(x, 11) ^ RR(x, 25)); } |
||||||
|
|
||||||
|
private static final int RHO0(int x) { return (RR(x, 7) ^ RR(x, 18) ^ SS(x, 3)); } |
||||||
|
private static final int RHO1(int x) { return (RR(x, 17) ^ RR(x, 19) ^ SS(x, 10)); } |
||||||
|
|
||||||
|
private static final int abcdefgh_a = 0; |
||||||
|
private static final int abcdefgh_b = 1; |
||||||
|
private static final int abcdefgh_c = 2; |
||||||
|
private static final int abcdefgh_d = 3; |
||||||
|
private static final int abcdefgh_e = 4; |
||||||
|
private static final int abcdefgh_f = 5; |
||||||
|
private static final int abcdefgh_g = 6; |
||||||
|
private static final int abcdefgh_h = 7; |
||||||
|
|
||||||
|
private static final void FF(int[] abcdefgh, int a, int b, int c, int d, int e, int f, int g, int h, int[] X, int j) { |
||||||
|
long T1; |
||||||
|
|
||||||
|
T1 = Common.intToUnsigned(abcdefgh[h]) + Common.intToUnsigned(Sigma1(abcdefgh[e])) + Common.intToUnsigned(Ch(abcdefgh[e], abcdefgh[f], abcdefgh[g])) + Common.intToUnsigned(SHA256_K[j]) + Common.intToUnsigned(X[j]); |
||||||
|
abcdefgh[d] += T1; |
||||||
|
abcdefgh[h] = (int)(T1 + Common.intToUnsigned(Sigma0(abcdefgh[a])) + Common.intToUnsigned(Maj(abcdefgh[a], abcdefgh[b], abcdefgh[c]))); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int GetData(byte[] x, int x_offset) { |
||||||
|
return Common.byte_to_int(x, x_offset, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
// o SHA256_Transform() : 512 비트 단위 블록의 메시지를 입력 받아 연쇄변수를 갱신하는 압축 함수로써
|
||||||
|
// 4 라운드(64 단계)로 구성되며 8개의 연쇄변수(a, b, c, d, e, f, g, h)를 사용
|
||||||
|
// o 입력 : Message - 입력 메시지의 포인터 변수
|
||||||
|
// ChainVar - 연쇄변수의 포인터 변수
|
||||||
|
// o 출력 :
|
||||||
|
//*********************************************************************************************************************************
|
||||||
|
private static void SHA256_Transform(byte[] Message, int[] ChainVar) { |
||||||
|
int abcdefgh[] = new int[8]; |
||||||
|
int T1[] = new int[1]; |
||||||
|
int X[] = new int[64]; |
||||||
|
int j; |
||||||
|
|
||||||
|
for (j = 0; j < 16; j++) |
||||||
|
X[j] = GetData(Message, j*4); |
||||||
|
|
||||||
|
for (j = 16; j < 64; j++) |
||||||
|
X[j] = (int)(Common.intToUnsigned(RHO1(X[j - 2])) + Common.intToUnsigned(X[j - 7]) + Common.intToUnsigned(RHO0(X[j - 15])) + Common.intToUnsigned(X[j - 16])); |
||||||
|
|
||||||
|
abcdefgh[abcdefgh_a] = ChainVar[0]; |
||||||
|
abcdefgh[abcdefgh_b] = ChainVar[1]; |
||||||
|
abcdefgh[abcdefgh_c] = ChainVar[2]; |
||||||
|
abcdefgh[abcdefgh_d] = ChainVar[3]; |
||||||
|
abcdefgh[abcdefgh_e] = ChainVar[4]; |
||||||
|
abcdefgh[abcdefgh_f] = ChainVar[5]; |
||||||
|
abcdefgh[abcdefgh_g] = ChainVar[6]; |
||||||
|
abcdefgh[abcdefgh_h] = ChainVar[7]; |
||||||
|
|
||||||
|
for (j = 0; j < 64; j += 8) |
||||||
|
{ |
||||||
|
FF(abcdefgh, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, X, j + 0); |
||||||
|
FF(abcdefgh, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, X, j + 1); |
||||||
|
FF(abcdefgh, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, X, j + 2); |
||||||
|
FF(abcdefgh, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, X, j + 3); |
||||||
|
FF(abcdefgh, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, abcdefgh_d, X, j + 4); |
||||||
|
FF(abcdefgh, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, abcdefgh_c, X, j + 5); |
||||||
|
FF(abcdefgh, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, abcdefgh_b, X, j + 6); |
||||||
|
FF(abcdefgh, abcdefgh_b, abcdefgh_c, abcdefgh_d, abcdefgh_e, abcdefgh_f, abcdefgh_g, abcdefgh_h, abcdefgh_a, X, j + 7); |
||||||
|
} |
||||||
|
|
||||||
|
ChainVar[0] += abcdefgh[abcdefgh_a]; |
||||||
|
ChainVar[1] += abcdefgh[abcdefgh_b]; |
||||||
|
ChainVar[2] += abcdefgh[abcdefgh_c]; |
||||||
|
ChainVar[3] += abcdefgh[abcdefgh_d]; |
||||||
|
ChainVar[4] += abcdefgh[abcdefgh_e]; |
||||||
|
ChainVar[5] += abcdefgh[abcdefgh_f]; |
||||||
|
ChainVar[6] += abcdefgh[abcdefgh_g]; |
||||||
|
ChainVar[7] += abcdefgh[abcdefgh_h]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 연쇄변수와 길이변수를 초기화하는 함수 |
||||||
|
@param Info : SHA256_Process 호출 시 사용되는 구조체 |
||||||
|
*/ |
||||||
|
public static void SHA256_Init( SHA256_INFO Info ) { |
||||||
|
Info.uChainVar[0] = 0x6a09e667; |
||||||
|
Info.uChainVar[1] = 0xbb67ae85; |
||||||
|
Info.uChainVar[2] = 0x3c6ef372; |
||||||
|
Info.uChainVar[3] = 0xa54ff53a; |
||||||
|
Info.uChainVar[4] = 0x510e527f; |
||||||
|
Info.uChainVar[5] = 0x9b05688c; |
||||||
|
Info.uChainVar[6] = 0x1f83d9ab; |
||||||
|
Info.uChainVar[7] = 0x5be0cd19; |
||||||
|
|
||||||
|
Info.uHighLength = Info.uLowLength = Info.remainNum = 0; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 연쇄변수와 길이변수를 초기화하는 함수 |
||||||
|
@param Info : SHA256_Init 호출하여 초기화된 구조체(내부적으로 사용된다.) |
||||||
|
@param pszMessage : 사용자 입력 평문 |
||||||
|
@param inLen : 사용자 입력 평문 길이 |
||||||
|
*/ |
||||||
|
public static void SHA256_Process( SHA256_INFO Info, byte[] pszMessage, int uDataLen ) { |
||||||
|
/* |
||||||
|
int pszMessage_offset = Info.remainNum; |
||||||
|
|
||||||
|
if((Info.uLowLength += (uDataLen << 3)) < 0) { |
||||||
|
Info.uHighLength++; |
||||||
|
} |
||||||
|
|
||||||
|
Info.uHighLength += Common.URShift(uDataLen,29); |
||||||
|
|
||||||
|
while (uDataLen + pszMessage_offset >= SHA256_DIGEST_BLOCKLEN) { |
||||||
|
Common.arraycopy_offset(Info.szBuffer, pszMessage_offset, pszMessage, 0, SHA256_DIGEST_BLOCKLEN); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
pszMessage_offset += SHA256_DIGEST_BLOCKLEN - pszMessage_offset; |
||||||
|
uDataLen -= SHA256_DIGEST_BLOCKLEN - pszMessage_offset; |
||||||
|
pszMessage_offset = 0; |
||||||
|
} |
||||||
|
|
||||||
|
Common.arraycopy_offset(Info.szBuffer, pszMessage_offset, pszMessage, 0, uDataLen); |
||||||
|
Info.remainNum = pszMessage_offset + uDataLen; |
||||||
|
|
||||||
|
*/ |
||||||
|
int pszMessage_offset; |
||||||
|
|
||||||
|
if((Info.uLowLength += (uDataLen << 3)) < 0) { |
||||||
|
Info.uHighLength++; |
||||||
|
} |
||||||
|
|
||||||
|
Info.uHighLength += Common.URShift(uDataLen,29); |
||||||
|
|
||||||
|
pszMessage_offset = 0; |
||||||
|
while (uDataLen >= SHA256_DIGEST_BLOCKLEN) { |
||||||
|
Common.arraycopy_offset(Info.szBuffer, 0, pszMessage, pszMessage_offset, SHA256_DIGEST_BLOCKLEN); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
pszMessage_offset += SHA256_DIGEST_BLOCKLEN; |
||||||
|
uDataLen -= SHA256_DIGEST_BLOCKLEN; |
||||||
|
} |
||||||
|
|
||||||
|
Common.arraycopy_offset(Info.szBuffer, 0, pszMessage, pszMessage_offset, uDataLen); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 메시지 덧붙이기와 길이 덧붙이기를 수행한 후 마지막 메시지 블록을 가지고 압축함수를 호출하는 함수 |
||||||
|
@param Info : SHA256_Init 호출하여 초기화된 구조체(내부적으로 사용된다.) |
||||||
|
@param pszDigest : 암호문 |
||||||
|
*/ |
||||||
|
public static void SHA256_Close( SHA256_INFO Info, byte[] pszDigest ) { |
||||||
|
int i, Index; |
||||||
|
|
||||||
|
Index = Common.URShift(Info.uLowLength, 3) % SHA256_DIGEST_BLOCKLEN; |
||||||
|
Info.szBuffer[Index++] = (byte)0x80; |
||||||
|
|
||||||
|
if (Index > SHA256_DIGEST_BLOCKLEN - 8) { |
||||||
|
Common.arrayinit_offset(Info.szBuffer, Index, (byte)0, SHA256_DIGEST_BLOCKLEN - Index); |
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
Common.arrayinit(Info.szBuffer, (byte)0, SHA256_DIGEST_BLOCKLEN - 8); |
||||||
|
} |
||||||
|
else { |
||||||
|
Common.arrayinit_offset(Info.szBuffer, Index, (byte)0, SHA256_DIGEST_BLOCKLEN - Index - 8); |
||||||
|
} |
||||||
|
|
||||||
|
if(ENDIAN == Common.LITTLE_ENDIAN) { |
||||||
|
Info.uLowLength = ENDIAN_REVERSE_ULONG(Info.uLowLength); |
||||||
|
Info.uHighLength = ENDIAN_REVERSE_ULONG(Info.uHighLength); |
||||||
|
} |
||||||
|
|
||||||
|
Common.int_to_byte_unit(Info.szBuffer, ((int)(SHA256_DIGEST_BLOCKLEN / 4 - 2))*4, Info.uHighLength, ENDIAN); |
||||||
|
Common.int_to_byte_unit(Info.szBuffer, ((int)(SHA256_DIGEST_BLOCKLEN / 4 - 1))*4, Info.uLowLength, ENDIAN); |
||||||
|
|
||||||
|
SHA256_Transform(Info.szBuffer, Info.uChainVar); |
||||||
|
|
||||||
|
for (i = 0; i < SHA256_DIGEST_VALUELEN; i += 4) |
||||||
|
BIG_D2B((Info.uChainVar)[i / 4], pszDigest, i); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
@brief 사용자 입력 평문을 한번에 처리 |
||||||
|
@param pszMessage : 사용자 입력 평문 |
||||||
|
@param pszDigest : 암호문 |
||||||
|
@remarks 내부적으로 SHA256_Init, SHA256_Process, SHA256_Close를 호출한다. |
||||||
|
*/ |
||||||
|
public static void SHA256_Encrpyt( byte[] pszMessage, int uPlainTextLen, byte[] pszDigest ) { |
||||||
|
SHA256_INFO info = new SHA256_INFO(); |
||||||
|
SHA256_Init( info ); |
||||||
|
SHA256_Process( info, pszMessage, uPlainTextLen ); |
||||||
|
SHA256_Close( info, pszDigest ); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static class SHA256_INFO { |
||||||
|
public int uChainVar[] = new int[SHA256_DIGEST_VALUELEN / 4]; |
||||||
|
public int uHighLength; |
||||||
|
public int uLowLength; |
||||||
|
public int remainNum; |
||||||
|
public byte szBuffer[] = new byte[SHA256_DIGEST_BLOCKLEN]; |
||||||
|
} |
||||||
|
|
||||||
|
public static class Common { |
||||||
|
|
||||||
|
public static final int BIG_ENDIAN = 0; |
||||||
|
public static final int LITTLE_ENDIAN = 1; |
||||||
|
|
||||||
|
public static void arraycopy(byte[] dst, byte[] src, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[i] = src[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arraycopy_offset(byte[] dst, int dst_offset, byte[] src, int src_offset, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[dst_offset+i] = src[src_offset+i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arrayinit(byte[] dst, byte value, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[i] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void arrayinit_offset(byte[] dst, int dst_offset, byte value, int length) { |
||||||
|
for(int i=0; i<length; i++) { |
||||||
|
dst[dst_offset+i] = value; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void memcpy(int[] dst, byte[] src, int length, int ENDIAN) { |
||||||
|
int iLen = length / 4; |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
byte_to_int(dst, i, src, i*4, ENDIAN); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void memcpy(int[] dst, int[] src, int src_offset, int length) { |
||||||
|
int iLen = length / 4 + ((length % 4 != 0)?1:0); |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
dst[i] = src[src_offset+i]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void set_byte_for_int(int[] dst, int b_offset, byte value, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
int shift_value = (3-b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int mask_value2 = ~mask_value; |
||||||
|
int value2 = (value&0x0ff) << shift_value; |
||||||
|
dst[b_offset/4] = (dst[b_offset/4] & mask_value2) | (value2 & mask_value); |
||||||
|
} else { |
||||||
|
int shift_value = (b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int mask_value2 = ~mask_value; |
||||||
|
int value2 = (value&0x0ff) << shift_value; |
||||||
|
dst[b_offset/4] = (dst[b_offset/4] & mask_value2) | (value2 & mask_value); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static byte get_byte_for_int(int[] src, int b_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
int shift_value = (3-b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int value = (src[b_offset/4] & mask_value) >> shift_value; |
||||||
|
return (byte)value; |
||||||
|
} else { |
||||||
|
int shift_value = (b_offset%4)*8; |
||||||
|
int mask_value = 0x0ff << shift_value; |
||||||
|
int value = (src[b_offset/4] & mask_value) >> shift_value; |
||||||
|
return (byte)value; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static byte[] get_bytes_for_ints(int[] src, int offset, int ENDIAN) { |
||||||
|
int iLen = src.length-offset; |
||||||
|
byte[] result = new byte[(iLen)*4]; |
||||||
|
for(int i=0; i<iLen; i++) { |
||||||
|
int_to_byte(result, i*4, src, offset+i, ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public static void byte_to_int(int[] dst, int dst_offset, byte[] src, int src_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
dst[dst_offset] = ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} else { |
||||||
|
dst[dst_offset] = ((0x0ff&src[src_offset])) | ((0x0ff&src[src_offset+1]) << 8) | ((0x0ff&src[src_offset+2]) << 16) | ((0x0ff&src[src_offset+3]) << 24); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static int byte_to_int(byte[] src, int src_offset, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
return ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} else { |
||||||
|
return ((0x0ff&src[src_offset])) | ((0x0ff&src[src_offset+1]) << 8) | ((0x0ff&src[src_offset+2]) << 16) | ((0x0ff&src[src_offset+3]) << 24); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static int byte_to_int_big_endian(byte[] src, int src_offset) { |
||||||
|
return ((0x0ff&src[src_offset]) << 24) | ((0x0ff&src[src_offset+1]) << 16) | ((0x0ff&src[src_offset+2]) << 8) | ((0x0ff&src[src_offset+3])); |
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte(byte[] dst, int dst_offset, int[] src, int src_offset, int ENDIAN) { |
||||||
|
int_to_byte_unit(dst, dst_offset, src[src_offset], ENDIAN); |
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte_unit(byte[] dst, int dst_offset, int src, int ENDIAN) { |
||||||
|
if(ENDIAN == BIG_ENDIAN) { |
||||||
|
dst[dst_offset] = (byte)((src>> 24) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src) & 0x0ff); |
||||||
|
} else { |
||||||
|
dst[dst_offset] = (byte)((src) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src >> 24) & 0x0ff); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static void int_to_byte_unit_big_endian(byte[] dst, int dst_offset, int src) { |
||||||
|
dst[dst_offset] = (byte)((src>> 24) & 0x0ff); |
||||||
|
dst[dst_offset+1] = (byte)((src >> 16) & 0x0ff); |
||||||
|
dst[dst_offset+2] = (byte)((src >> 8) & 0x0ff); |
||||||
|
dst[dst_offset+3] = (byte)((src) & 0x0ff); |
||||||
|
} |
||||||
|
|
||||||
|
public static int URShift(int x, int n) { |
||||||
|
if(n == 0) |
||||||
|
return x; |
||||||
|
if(n >= 32) |
||||||
|
return 0; |
||||||
|
int v = x >> n; |
||||||
|
int v_mask = ~(0x80000000 >> (n-1)); |
||||||
|
return v & v_mask; |
||||||
|
} |
||||||
|
|
||||||
|
public static final long INT_RANGE_MAX = (long)Math.pow(2, 32); |
||||||
|
|
||||||
|
public static long intToUnsigned(int x) { |
||||||
|
if(x >= 0) |
||||||
|
return x; |
||||||
|
return x + INT_RANGE_MAX; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) |
||||||
|
{ |
||||||
|
byte pbData[] = {(byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F, |
||||||
|
(byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F}; |
||||||
|
byte pbData1[] = {(byte)0x61}; |
||||||
|
|
||||||
|
byte pbCipher[] = new byte[32]; |
||||||
|
byte pbPlain[] = new byte[16]; |
||||||
|
|
||||||
|
System.out.print("[ Test SHA256 reference code ]"+"\n"); |
||||||
|
System.out.print("\n\n"); |
||||||
|
System.out.print("[ Test HASH mode ]"+"\n"); |
||||||
|
System.out.print("\n"); |
||||||
|
|
||||||
|
int Plaintext_length = 1; |
||||||
|
|
||||||
|
for(int k=0; k<30; k++) |
||||||
|
{ |
||||||
|
|
||||||
|
System.out.print("Plaintext\t: "); |
||||||
|
for (int i=0; i<Plaintext_length; i++) System.out.print(Integer.toHexString(0xff&pbData[i])+" "); |
||||||
|
System.out.print("\n"); |
||||||
|
|
||||||
|
// Encryption
|
||||||
|
SHA256_Encrpyt( pbData, Plaintext_length, pbCipher ); |
||||||
|
|
||||||
|
System.out.print("Ciphertext\t: "); |
||||||
|
for (int i=0; i<32; i++) System.out.print(Integer.toHexString(0xff&pbCipher[i])+" "); |
||||||
|
System.out.print("\n\n"); |
||||||
|
|
||||||
|
Plaintext_length++; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
System.out.print("Plaintext\t: "); |
||||||
|
for (int i=0; i<1; i++) System.out.print(Integer.toHexString(0xff&pbData1[i])+" "); |
||||||
|
System.out.print("\n"); |
||||||
|
// Encryption
|
||||||
|
SHA256_Encrpyt( pbData1, 1, pbCipher ); |
||||||
|
System.out.print("Ciphertext\t: "); |
||||||
|
for (int i=0; i<32; i++) System.out.print(Integer.toHexString(0xff&pbCipher[i])+" "); |
||||||
|
System.out.print("\n\n"); |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue