프로젝트 중 갑자기 잘 되던 https 통신이 되지 않았다.
확인해보니 서버 측에서 더 이상 TLS1.0을 지원하지 않는다는 답변을 받았다.
WireShark에서 확인해보니
Alert (Level: Fatal, Description: Protocol Version) 라는 메세지가 떴다.
프로토콜 버전이 맞지 않아서 발생한 에러였다.
TLS1.0 대신 TLS1.2를 사용하려면 간단하게 Java8을 사용하면 되지만
나는 Java6을 사용해야만 했기에 Java6에서 TLS1.2 통신을 하는 방법을 찾아보았다.
※ Java 버전에서 지원되는 TLS 버전
Java Version | SSL / TLS default | Other Supported Versions |
Java6 | TLS1.0 | TLS 1.1 (update 111 and later), SSLv3.0* |
Java7 | TLS1.0 | TLS 1.2, TLS 1.1, SSLv3.0* |
Java8 | TLS1.2 | TLS 1.1, TLS 1.0, SSLv3.0* |
* SSLv3 support disabled in January, 2015 patch releases
* 참고 : https://www.ateam-oracle.com/tls-and-java
그렇게 구글링 끝에 나름 간단하게 java6에서 tls1.2통신을 할 수 있는 방법을 찾았다.
바로 Bouncy Castle라는 라이브러리를 이용한 것이었는데, 해당하는 jar파일을 다운받아야 했다.
https://www.bouncycastle.org/latest_releases.html
해당 사이트에 접속하여 bcprov-jdk15to18-168.jar 및 bctls-jdk15to18-168.jar 를 다운로드한 후
${JAVA_HOME}/jre/lib/ext 폴더에 복사한다.
그 후, ${JAVA_HOME}/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
이렇게 provider 리스트에 BouncyCastle 관련 provider를 추가하였다.
나의 경우는 스택오버플로우 내용에 따라 앞에 추가하였지만 뒤에 추가해도 무방할 것 같다.
여기에 추가로 최신버전 JCE파일이 필요하다.
https://www.oracle.com/java/technologies/jce-6-download.html
해당 경로에서 jce_policy-6.zip 파일을 다운받은 후 압축을 해제한다.
그 후, 다시 ${JAVA_HOME}/jre/lib/security 폴더로 이동하여 다음 두 가지 파일을 덮어쓴다.
US_export_policy.jar
local_policy.jar
덮어쓰기 후 모든 세팅이 완료된다.
만약 최신버전 JCE파일을 사용하지 않는 경우,
InvalidKeyException : Illegal key size 이와 같은 에러가 날 수 있다.
아무튼 이와 같이 Bouncy Castle을 사용하여 코드 수정 없이도 java6 에서 TLS1.2 통신을 지원할 수 있었다.
어쩔 수 없이 java6을 사용해야 하는 경우에만 참고하면 좋을 것 같다.
* 참고한 stackoverflow 답변
https://stackoverflow.com/questions/33364100/how-to-use-tls-1-2-in-java-6