· 7 years ago · Dec 20, 2018, 03:36 AM
1/*
2 * To change this license header, choose License Headers in Project Properties.
3 * To change this template file, choose Tools | Templates
4 * and open the template in the editor.
5 */
6package com.artivisi.payment.merchant.service.bukopin;
7
8import com.artivisi.payment.merchant.service.bukopin.constants.BukopinPlnConstant;
9import com.artivisi.payment.model.merchant.exception.MerchantGatewayException;
10import java.util.List;
11import java.util.Map;
12import javax.annotation.Resource;
13import javax.crypto.Cipher;
14import javax.crypto.IllegalBlockSizeException;
15import javax.crypto.SecretKey;
16import javax.crypto.SecretKeyFactory;
17import javax.crypto.spec.DESedeKeySpec;
18import org.hibernate.SessionFactory;
19import org.slf4j.Logger;
20import org.slf4j.LoggerFactory;
21import org.springframework.beans.factory.annotation.Autowired;
22import org.springframework.stereotype.Component;
23import org.springframework.transaction.annotation.Transactional;
24
25import static org.springframework.transaction.annotation.Propagation.REQUIRES_NEW;
26
27/**
28 *
29 * @author anggi
30 */
31@Component
32@Transactional(propagation = REQUIRES_NEW)
33public class BukopinSessionKeyService {
34
35 @Autowired
36 private SessionFactory sessionFactory;
37 private static final Logger LOGGER = LoggerFactory.getLogger(BukopinSessionKeyService.class);
38
39 @Resource(name = "bukopinSessionKeys")
40 private Map<String, String> bukopinSessionKeyRegistry;
41
42
43 //save session key ke map
44 public void saveToUtilMap(String key, String sessionKey){
45 LOGGER.info("save session key ke map util key : {}, sessionKey: {}",key , sessionKey);
46 bukopinSessionKeyRegistry.put(key, sessionKey);
47 }
48
49 //ambil session key dari map
50 public String getSessionKeyFromUtilMap(String key){
51 String bukopinSessionKey = bukopinSessionKeyRegistry.get(key);
52 if (bukopinSessionKey == null || bukopinSessionKey.isEmpty()) {
53 LOGGER.warn("[SESSION KEY] - [INVALID] {SESSION KEY:" + key + " IS EMPTY}");
54 return null;
55 }
56 LOGGER.info("get session key from map util [key: {}, sessionKey:{}] ",key,bukopinSessionKey);
57 return bukopinSessionKey;
58 }
59
60 public String generateToken(String stan, String key) throws MerchantGatewayException {
61 try {
62 String sessionKey = getSessionKeyFromUtilMap(key);
63 String decryptedSessionKey = decrypt(sessionKey, BukopinPlnConstant.BUKOPIN_PRIVATE_KEY);
64 return encrypt(stan.concat("FFFF"), decryptedSessionKey);
65 } catch (Exception ex) {
66 LOGGER.error("[ERROR GENERATE TOKEN ] : " + ex.getMessage(), ex);
67 throw new MerchantGatewayException("[ERROR GENERATE TOKEN ] : " + ex.getMessage());
68 }
69 }
70
71 private String encrypt(String message, String secretKey) throws MerchantGatewayException {
72 LOGGER.debug("TEXT TO BE ENCRYPTED : " + message);
73 LOGGER.debug("PRIVATE KEY : " + secretKey);
74 try {
75 DESedeKeySpec keyspec = new DESedeKeySpec(getHexByteArray(secretKey));
76 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
77 SecretKey key = keyfactory.generateSecret(keyspec);
78
79 Cipher cipher = Cipher.getInstance("DESede/ECB/noPadding");
80 cipher.init(Cipher.ENCRYPT_MODE, key);
81
82 byte[] plainTextBytes = getHexByteArray(message);
83 byte[] buf = cipher.doFinal(plainTextBytes);
84
85 return getHexString(buf);
86 } catch (Exception ex) {
87 LOGGER.error("[ERROR ENCRYPTING DATA ] : " + ex.getMessage(), ex);
88 throw new MerchantGatewayException("[ERROR ENCRYPTING DATA ] : " + ex.getMessage());
89 }
90 }
91
92 private String decrypt(String encryptedText, String secretKey) throws MerchantGatewayException {
93 LOGGER.debug("TEXT TO BE DECRYPTED : " + encryptedText);
94 LOGGER.debug("PRIVATE KEY : " + secretKey);
95 try {
96 DESedeKeySpec keyspec = new DESedeKeySpec(getHexByteArray(secretKey));
97 SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
98 SecretKey key = keyfactory.generateSecret(keyspec);
99
100 Cipher decipher = Cipher.getInstance("DESede/ECB/noPadding");
101 decipher.init(Cipher.DECRYPT_MODE, key);
102
103 byte[] plainText = decipher.doFinal(getHexByteArray(encryptedText));
104
105 return getHexString(plainText);
106 } catch (Exception ex) {
107 LOGGER.error("[ERROR DECRYPTING DATA ] : " + ex.getMessage(), ex);
108 throw new MerchantGatewayException("[ERROR DECRYPTING DATA ] : " + ex.getMessage());
109 }
110 }
111
112 private static String getHexString(byte[] input) {
113 StringBuilder strBuilder = new StringBuilder();
114 for (byte hexByte : input) {
115 int res = 0xFF & hexByte;
116 String hexString = Integer.toHexString(res);
117 if (hexString.length() == 1) {
118 strBuilder.append(0);
119 }
120 strBuilder.append(hexString);
121
122 }
123
124 return strBuilder.toString();
125 }
126
127 private static byte[] getHexByteArray(String input)
128 throws IllegalBlockSizeException {
129
130 int[] resultHex = getHexIntArray(input);
131 byte[] returnBytes = new byte[resultHex.length];
132 for (int cnt = 0; cnt < resultHex.length; cnt++) {
133 returnBytes[cnt] = (byte) resultHex[cnt];
134 }
135 return returnBytes;
136 }
137
138 private static int[] getHexIntArray(String input)
139 throws IllegalBlockSizeException {
140 if (input.length() % 2 != 0) {
141 throw new IllegalBlockSizeException(
142 "Invalid Hex String, Hex representation length is not a multiple of 2");
143 }
144 int[] resultHex = new int[input.length() / 2];
145 for (int iCnt1 = 0; iCnt1 < input.length(); iCnt1++) {
146 String byteString = input.substring(iCnt1, ++iCnt1 + 1);
147 int hexOut = Integer.parseInt(byteString, 16);
148 resultHex[iCnt1 / 2] = (hexOut & 0x000000ff);
149 }
150 return resultHex;
151 }
152}