以下问题, 求php大神指点!
用stream_socket_client连接一个java写的TLS服务器,对方提供了以下的证书文件给我:
---------------------------------------------
newcert_xx.pem(证书)
newkey_xx.pem(私钥, 密码为xxxx)
xx.pfx
ca.crt
newcert.cer
---------------------------------------------
对于PHP我就只关心.pem的文件, 其他的先不管了(我都快被搞晕了,都是证书啊,key啊)
以下是我的php code,执行的结果是"Failed to connect: 0" , 既然连接出错,为什么Error又为空,
按道理这样调用应该没问题的,不知道是证书的问题还是他们服务端的问题, 之前我用C#(用.pfx文件)来调也是不成功. <?
header("Content-type: text/html");
$req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd\"><hello/></epp>";
$req = utf8_encode($req);
$protocols = 'ssl';
$cnnicServer = "ssl://srs.server.com:3121";
$caPath = 'newcert_xx.pem';
$certPath = 'newkey_xx.pem';
$context = stream_context_create();
//是否需要验证SSL证书。
stream_context_set_option($context, $protocols, 'verify_peer', true); //stream_context_set_option($context, $protocols, 'allow_self_signed', true);//是否允许自签名证书 //当verify_peer为true时,用来验证远端证书所用到的CA证书
stream_context_set_option($context, $protocols, 'cafile', $caPath); //本地证书路径。必须是PEM格式并且包含本地的证书及私钥。也可以包含证书颁发者证书链。
stream_context_set_option($context, $protocols, 'local_cert',$certPath); //local_cert文件的密码
stream_context_set_option($context, $protocols, 'passphrase',xxxx);
$fp = stream_socket_client($cnnicServer,$errno, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $context);
if (!$fp) {
echo "Failed to connect: $errno $errstr".
}
fwrite($fp, $req);
echo "<p>have been send to server</p>".$fp;
echo fread($fp, 1024 * 8);
fclose($fp);
echo "<p>close connect</p>";
?>
用stream_socket_client连接一个java写的TLS服务器,对方提供了以下的证书文件给我:
---------------------------------------------
newcert_xx.pem(证书)
newkey_xx.pem(私钥, 密码为xxxx)
xx.pfx
ca.crt
newcert.cer
---------------------------------------------
对于PHP我就只关心.pem的文件, 其他的先不管了(我都快被搞晕了,都是证书啊,key啊)
以下是我的php code,执行的结果是"Failed to connect: 0" , 既然连接出错,为什么Error又为空,
按道理这样调用应该没问题的,不知道是证书的问题还是他们服务端的问题, 之前我用C#(用.pfx文件)来调也是不成功. <?
header("Content-type: text/html");
$req = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd\"><hello/></epp>";
$req = utf8_encode($req);
$protocols = 'ssl';
$cnnicServer = "ssl://srs.server.com:3121";
$caPath = 'newcert_xx.pem';
$certPath = 'newkey_xx.pem';
$context = stream_context_create();
//是否需要验证SSL证书。
stream_context_set_option($context, $protocols, 'verify_peer', true); //stream_context_set_option($context, $protocols, 'allow_self_signed', true);//是否允许自签名证书 //当verify_peer为true时,用来验证远端证书所用到的CA证书
stream_context_set_option($context, $protocols, 'cafile', $caPath); //本地证书路径。必须是PEM格式并且包含本地的证书及私钥。也可以包含证书颁发者证书链。
stream_context_set_option($context, $protocols, 'local_cert',$certPath); //local_cert文件的密码
stream_context_set_option($context, $protocols, 'passphrase',xxxx);
$fp = stream_socket_client($cnnicServer,$errno, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $context);
if (!$fp) {
echo "Failed to connect: $errno $errstr".
}
fwrite($fp, $req);
echo "<p>have been send to server</p>".$fp;
echo fread($fp, 1024 * 8);
fclose($fp);
echo "<p>close connect</p>";
?>
if (this.sslContext != null) {
return this.sslContext;
}
try {
sslContext = SSLContext.getInstance("TLS");
KeyManagerFactory kmf;
TrustManagerFactory tmf;
KeyStore ks;
KeyStore ts; if (tlsArgs == null) {
logger.error("can't load properties from init()");
} String ksName = tlsArgs.getProperty("registrar.keyStore", "xxxx02kw.keystore");
String tsName = tlsArgs.getProperty("registrar.trustStore", "jssecacerts.02kw.keystore"); String ksPass = tlsArgs.getProperty("registrar.keyStorePassword", "passphrase");
String tsPass = tlsArgs.getProperty("registrar.trustStorePassword", "passphrase"); tmf = TrustManagerFactory.getInstance("SunX509");
kmf = KeyManagerFactory.getInstance("SunX509"); ks = KeyStore.getInstance("JKS");
ts = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(ksName), ksPass.toCharArray());
ts.load(new FileInputStream(tsName), tsPass.toCharArray());
kmf.init(ks, ksPass.toCharArray());
tmf.init(ts); String secRandomAlgorithm = "SHA1PRNG";
SecureRandom secRandom = SecureRandom.getInstance(secRandomAlgorithm); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), secRandom);
return this.sslContext;
} catch (Exception e) {
logger.error("can't build SSLContext : " + e.getMessage());
throw new RuntimeException("can't build SSLContext");
}
throw new RuntimeException("can't build SSLContext");
}//创建一个新的session
EppSessionImpl sesImpl = new EppSessionImpl() SSLContext ctx = SSLContext.getInstance("TLS");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("xxxx_cert/" + regID + ".jks"), "passphrase"
.toCharArray());
ts.load(new FileInputStream("xxxx_cert/ca.keystore"), "passphrase"
.toCharArray());
kmf.init(ks, "passphrase".toCharArray());
tmf.init(ts); ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); sesImpl.setSslContext(ctx); EppGreeting greeting;
greeting = sesImpl.connect(host, port);
System.out.println(greeting.toString());