얼마전에 Tomcat 8.5(JDK 8) + MSSQL2008 로 신규 구성된 시스템에서 Application Deploy 후 테스트 중에 
아래와 같은 Exception이 발생한다고 하여 확인해보았습니다.
 
Application에서 직접 DB연결을 하고 있는데, DB 연결 시에 아래와 같은 Exception이 발생하면서
“이 driver에서는 해당 알고리즘을 지원할 수 없다”는 문구와 함께 출력되고 있었습니다.
 
java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
 
CertificateException? 흔히 DB 커넥션 연결오류로 만나는 Exception이나 Error와는 다른 타입이네요.
DB로의 Secure 커넥션을 생성하는데에 사용되는 알고리즘에 문제가 있나 봅니다.
 
MSSQL JDBC Driver에서 제공하는 프로퍼티들과 실제 Application에서 설정한 부분들을 확인 해봐야겠지만..
아마도 아래와 같은 방식으로 커넥션을 시도하고 있었을거라 생각됩니다.
 
String connectionUrl =   
    "jdbc:sqlserver://localhost:1433;" +  
     "databaseName=AdventureWorks;integratedSecurity=true;" +  
     "encrypt=true;trustServerCertificate=true";  
 
MSSQL 도큐먼트에 아래와 같은 내용이 있어 참고로 적어봅니다.
 
(참고URL1 : https://docs.microsoft.com/en-us/sql/connect/jdbc/connecting-with-ssl-encryption)
 
When the encrypt property is set to true and the trustServerCertificate property is set to false, the Microsoft JDBC Driver for SQL Server will validate the SQL Server SSL certificate. Validating the server certificate is a part of the SSL handshake and ensures that the server is the correct server to connect to. In order to validate the server certificate, the trust material must be supplied at connection time either by using trustStore and trustStorePassword connection properties explicitly, or by using the underlying Java Virtual Machine (JVM)'s default trust store implicitly.
 
 
이미 Exception에서 캐치하셨겠지만, MSSQL 도큐먼트에서 확인되는 내용에서처럼 위와 같은 설정에 의해
Application(client)에서 DB 연결 시 암호화를 요청하여 SSL handshake를 시도하였으나 서버 유효성 검사하는 과정에서 문제가 생긴 것으로 보입니다.
 
 
=====================================================================================
이외에도 CertificateException은 설정 문제로도 발생할 수 있는데요, “encrypt=true;trustServerCetificate=false” 로 설정하게 되면 아래와 같은 Exception이 발생하게 됩니다.
If the encrypt property is set to true and the trustServerCertificate property is set to false and if the server name in the connection string does not match the server name in the SQL Server SSL certificate, the following error will be issued: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "java.security.cert.CertificateException: Failed to validate the server name in a certificate during Secure Sockets Layer (SSL) initialization."
 
유사한 이슈로 아래 링크도 참고하면 좋을 것 같습니다.
(참고 URL2 : https://blogs.msdn.microsoft.com/dataaccesstechnologies/2016/11/30/intermittent-jdbc-connectivity-issue-the-driver-could-not-establish-a-secure-connection-to-sql-server-by-using-secure-sockets-layer-ssl-encryption-error-sql-server-returned-an-incomplete-respons/)
=====================================================================================
 
이번 문제는 설정 문제는 아닌 것 같죠?
 
Application과 JDBC드라이버에서 DB와의 통신을 위해 사용하는 알고리즘에 이슈가 있는 것 같네요.
 
jdk 8에서 SSL/TLS 커넥션 시 사용하는 알고리즘을 살펴봅니다. 
 
# jdk 8의 java.security 내 설정($JAVA_HOME/jre/lib/security)
   (참고 : jdk 9에서는 java.security 가 ($JAVA_HOME/conf/security/java.security 로 이동되었습니다.)
 
jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
jdk.tls.disabledAlgorithms=SSLv3, DH keySize < 768
 
jdk 6에서는 없던 설정으로 알고 있는데요, 제가 확인한 1.6.0_45 버전의 java.security에도 위의 설정은 찾아볼 수 없었습니다.
jdk 7 버전부터 추가된 설정으로 확인됩니다. jdk 7 부터 MD2, RSA 인데 키 사이즈가 1024미만인 경우에 대해 거부하도록 기본값이 바뀐거죠.
MD2는 아시겠지만 이미 오래전부터 insecure한 것으로 알려져왔기 때문에 이런 부분들이 반영되지 않았나 싶습니다.
 
아래 링크를 추가로 참고해보시면 아시겠지만 java도 버전업 되면서 보안적인 부분이 강화되고 있습니다.
(참고URL 3 : https://www.java.com/en/configure_crypto.html)
 
그래서,
java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
이거 어떻게 해결해야 할까요?
 
방법은 두 가지가 있습니다. 
1. Get a certificate with key size 1024 or greater.   (근본적으로는 이 방법을 선택해야겠지만요..제약 사항이 많겠죠?)
2. Change the following line in “java.security” file under “$JAVA_HOME/jre/lib/security”
 
2번 항목에서처럼 java.security 파일에서 아래 설정 항목들을 수정하거나 주석처리 하여 우회할 수 있습니다.
 
jdk.certpath.disabledAlgorithms=MD2
or
#jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
 
(참고 URL 4 : https://www.java-success.com/debugging-java-security-cert-certificateexception-certificates-does-not-conform-to-algorithm-constraints/)