티스토리 뷰

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);
  }
}

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함