以下问题, 求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>";
  ?>

解决方案 »

  1.   

    以下是服务端提供的用Java调用的方法的sample, 用php就出问题了.private SSLContext getSslContext() {
            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());
      

  2.   

    php大神呢???求指点