우리 서버 중 하나에서 예정대로 실행되는 .net 코드를 작성 중입니다. 실행의 일부는 SSL을 통해 일부 웹 자원 및 서비스와 통신하는 Java 실행 파일을 실행해야합니다.원격 호스트에서 X509 인증서 체인을 자동으로 다운로드
자바가 SSL을 통해 무언가를하고 있으며 원격 인증서의 체인에있는 모든 단일 인증서를 갖고 있지 않다면 Java는 절대적으로 적합합니다. 그래서 .net에서 https : // [뭐든지] .com 리소스를 특정 할 수 있어야하고 로컬에서 전체 원격 체인을 다운로드해야합니다.
왜 자동으로 처리하고 싶습니까? 배포를 간소화하고 오라클의 인증서 중 하나가 만료 될 때마다이 작업을 4 회 수행하고 다시 수행하지 않아도되기를 원합니다.
나는이 일을하고있다 :
X509Certificate2 lowestCert = SecurityHelper.DownloadSslCertificate(keyDownloadLocation);
X509Chain chain = new X509Chain();
chain.Build(lowestCert);
int counter = 0;
foreach (X509ChainElement el in chain.ChainElements) {
//Extract certificate
X509Certificate2 chainCert = el.Certificate;
//Come up with an alias and save location
string alias = certBaseName + counter;
string localLocation = Path.GetDirectoryName(
System.Reflection.Assembly.GetEntryAssembly().Location
) + @"\" +alias + ".cer";
//Save it locally
SecurityHelper.SaveCertificateToFile(chainCert, localLocation);
//Remove (if possible) and add to java's keystore
deleteKeyFromKeystore(
javaFolder,
alias,
certKeyStore,
SecurityHelper.GetEncryptedAppSetting("JavaKeystorePassword")
);
addKeytoKeyStore(
localLocation,
javaFolder,
alias,
certKeyStore,
SecurityHelper.GetEncryptedAppSetting("JavaKeystorePassword")
);
//Then delete
if (File.Exists(localLocation)) File.Delete(localLocation);
counter++;
}
SecurityHelper.DownloadSslCertificate는 웹 사이트의 URL에서 X509Certificate2를 생성하는 사용자 정의 방법이다.
"cert"는 가장 낮은 수준의 인증서이며이를 다시 얻을 수는 있지만 내가 할 수없는 일은 사슬에서 모든 것을 얻는 것입니다. chain.ChainElements는 체인의 나머지가 아직 기계에 설치되어 있지 않은 경우 여전히 1 레벨 깊이입니다. 내 문제는 이것이 (컴퓨터에) 완전히 알려지지 않은 새로운 URL이며, 스택을 올라가서 모든 것을 다운로드하고 싶다.
기계에 알려지지 않은 URL을 치고 체인의 모든 인증서를 프로그래밍 방식으로 다운로드하는 방법이 있습니까?
편집 :
public static X509Certificate2 DownloadSslCertificate(string strDNSEntry)
{
X509Certificate2 cert = null;
using (TcpClient client = new TcpClient())
{
client.Connect(strDNSEntry, 443);
SslStream ssl = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(
(sender, certificate, chain, sslPolicyErrors) => {
return true;
}
), null);
try
{
ssl.AuthenticateAsClient(strDNSEntry);
}
catch (AuthenticationException e)
{
ssl.Close();
client.Close();
return cert;
}
catch (Exception e)
{
ssl.Close();
client.Close();
return cert;
}
cert = new X509Certificate2(ssl.RemoteCertificate);
ssl.Close();
client.Close();
return cert;
}
}
편집 # 2 나를 위해 일한 원격 SSL 인증서를 얻기 위해이 솔루션은 검증 콜백 체인을 포착했다 : 나는 어 다운로드있어 어떻게 여기가 SSL 인증서입니다 SslStream.AuthenticateAsClient (url) 중에 발생합니다. AuthenticateAsClient는 로컬 "callbackChainElements 완료 시간에 의해 다음
public static X509Certificate2 DownloadSslCertificate(string url)
{
X509Certificate2 cert = null;
using (TcpClient client = new TcpClient())
{
client.Connect(url, 443);
SslStream ssl = new SslStream(client.GetStream(), false, CertificateValidationCallback, null);
try
{
ssl.AuthenticateAsClient(url); //will call CertificateValidationCallback
}
... 등
:
private static X509ChainElementCollection callbackChainElements = null;
private static bool CertificateValidationCallback(
Object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
callbackChainElements = chain.ChainElements;
return true;
}
그리고이 콜백으로 검증 킥오프하는, 내가 좋아하는 일을했다 "변수는 X509ChainElement 컬렉션으로 설정됩니다.
와우, 나는 누군가가 대답하고 얼마나 똑같은 짓을했는지 놀랍다! 나는 이것이 불가능하다고 생각했다. 나는 인증서를 얻는 방법을 보여주기 위해 내 게시물을 편집했습니다. 이것은 믿을 수있는 온라인에서 찾은 함수이므로 콜백을 수정하여 true를 반환했습니다. 너가 말하는게 이거니? 나는 여전히 단지 1 개의 사슬 요소만을 가지고있다. 감사! – Tor
글쎄, 내가 TcpClient에 익숙하지 않은데, 나는 HttpWebClient와 함께했다. 그래도 인증서 체인을 얻는 것이 큰 차이는 아니라고 생각합니다. 솔직하게, 나는 인증서 자체를 검사 할 것이다. 호스트에 바인드 된 인증서가 루트/중간 인증서가 연결된 유효하고 서명 된 인증서인지 또는 루트 인증서가 잘못 바인딩되어 있는지 확인할 수 있습니까? – mppowe
Chrome에서 검사했을 때 인증서 자체가 문제가되지 않으며 중급 CA가 있고 그 위에 루트가있는 경우 – Tor