Server Side Script/JAVA.Servlet.JSP
java 7에서 AES/CBC/PKCS5Padding TLS1.2 및 Cipher제한 과제
미련곰
2022. 5. 18. 17:19
TLS1.2 프로토콜만 허용하며 아래와같은 Cipher로 제한하는 서버측에 java7 환경의 클라이언트 REST 통신
JAVA8로 업글이 가장 편하겠지만 그럴수 없는 상황...
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 |
반나절 끝에 해결
- https://www.bouncycastle.org/latest_releases.html 에서 아래 4개의 파일 다운로드 후 jre/lib/ext 에 추가
- bcprov-ext-jdk15to18-171.jar - bcprov-jdk15to18-171.jar - bctls-jdk15to18-171.jar - bcutil-jdk15to18-171.jar |
- https://www.oracle.com/java/technologies/jce-7-download.html 에서 파일 다운로드 후 압축해제
- jre/lib/security 에 기존파일 백업 후 아래 파일 교체
- local_policy.jar - US_export_policy.jar |
- jre/lib/security/java.security 파일 백업 후 아래와 같이 내용 변경
- 기존 security.provider.1=sun.security.provider.Sun security.provider.2=sun.security.rsa.SunRsaSign security.provider.3=com.sun.net.ssl.internal.ssl.Provider security.provider.4=com.sun.crypto.provider.SunJCE security.provider.5=sun.security.jgss.SunProvider security.provider.6=com.sun.security.sasl.Provider security.provider.7=org.jcp.xml.dsig.internal.dom.XMLDSigRI security.provider.8=sun.security.smartcardio.SunPCSC security.provider.9=sun.security.mscapi.SunMSCAPI |
- 변경 security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider security.provider.2=org.bouncycastle.jsse.provider.BouncyCastleJsseProvider security.provider.3=sun.security.provider.Sun security.provider.4=sun.security.rsa.SunRsaSign security.provider.5=com.sun.net.ssl.internal.ssl.Provider security.provider.6=com.sun.crypto.provider.SunJCE security.provider.7=sun.security.jgss.SunProvider security.provider.8=com.sun.security.sasl.Provider security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI security.provider.10=sun.security.smartcardio.SunPCSC security.provider.11=sun.security.mscapi.SunMSCAPI ssl.SocketFactory.provider=org.bouncycastle.jsse.provider.SSLSocketFactoryImpl |
- 검증
package test; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; import org.apache.commons.codec.binary.Base64; import org.codehaus.jettison.json.JSONObject; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; public class Main { final static String secretKey = "1234567890"; final static String iv = secretKey.substring(0, 16); // 16bit public static String encrypt(String str) throws Exception { byte[] keyData = secretKey.getBytes(); SecretKey secureKey = new SecretKeySpec(keyData, "AES"); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.ENCRYPT_MODE, secureKey, new IvParameterSpec(iv.getBytes())); byte[] encrypted = c.doFinal(str.getBytes("UTF-8")); String enStr = new String(Base64.encodeBase64(encrypted)); return enStr; } public static String decrypt(String str) throws Exception { byte[] keyData = secretKey.getBytes(); SecretKey secureKey = new SecretKeySpec(keyData, "AES"); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, secureKey, new IvParameterSpec(iv.getBytes())); byte[] byteStr = Base64.decodeBase64(str.getBytes()); return new String(c.doFinal(byteStr), "UTF-8"); } public static Map<String, Object> getMapFromJsonObject(JSONObject jsonObj) throws java.io.IOException { Map<String, Object> map = null; try { map = new ObjectMapper().readValue(jsonObj.toString(), Map.class); } catch (JsonParseException e) { e.printStackTrace(); } catch (JsonMappingException e) { e.printStackTrace(); } return map; } public static void main(String[] args) { try { run(); } catch (Exception e) { e.printStackTrace(); } } public static void run() throws Exception { HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }); Map<String, Object> dataParam = new HashMap<String, Object>(); RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); ObjectMapper objectMapper = new ObjectMapper(); ObjectWriter prettyPrinter = objectMapper.writerWithDefaultPrettyPrinter(); String dataStr = objectMapper.writeValueAsString(dataParam); JSONObject jsonData = new JSONObject(); jsonData.put("data", encrypt(dataStr)); HttpEntity<String> request = new HttpEntity<String>(jsonData.toString(), headers); String resultAsJsonStr = restTemplate.postForObject("https://test.com", request, String.class); System.out.println(resultAsJsonStr); } } |