Java等同于OpenSSL s_client命令 [英] Java equivalent to OpenSSL s_client command

查看:389
本文介绍了Java等同于OpenSSL s_client命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将某些bash脚本转换为java,并且其中一个这样的脚本使用openssl作为参数使用openssl连接到服务器,以检查使用该vanity-url是否可连接.参见下面的命令

I have a requirement to convert certain bash scripts to java and one such script connects to a server using openssl with a vanity-url as a parameter to check if that is connectable using that vanity-url. See command below

/usr/bin/openssl s_client -connect api.sys.found1.cf.company.com:443 -servername www.app.company.com 2>/dev/null

我想在java中进行类似的活动并测试连通性.关于如何使用Java建立open-ssl连接的任何想法.这是我需要使用外部库吗?

I wanted to do the similar activity in java and test the connectivity. Any ideas on how to make a open-ssl connection using Java .. Is this something that I need to use external Library ?

推荐答案

我能够通过引用文档基本上,需要创建SSLEngine并与SNI

Basically, a SSLEngine needs to be created and make a successful handshake along with SNI

 private SocketChannel createSocketChannel() throws IOException {
        InetSocketAddress socketAddress = new InetSocketAddress(PROXY_ADDRESS, PROXY_PORT);
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.connect(socketAddress);
        socketChannel.configureBlocking(false);
        return socketChannel;

    }

private SSLContext createSSLContext() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext sslContext = SSLContext.getInstance(TLS_VERSION);
        sslContext.init(null,null,null);
        return sslContext;
    }




private SSLEngine createSSLEngine() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext sslContext = createSSLContext();
        SSLEngine sslEngine = sslContext.createSSLEngine(PROXY_ADDRESS, PROXY_PORT);
        sslEngine.setUseClientMode(true);

        List<SNIServerName> serverNameList = new ArrayList<>();
        serverNameList.add(new SNIHostName(SNI_HOST_NAME));
        SSLParameters sslParameters = sslEngine.getSSLParameters();
        sslParameters.setServerNames(serverNameList);

        sslEngine.setSSLParameters(sslParameters);

        return sslEngine;
    }

创建SSLEngine后,必须开始handShake

After creating SSLEngine, the handShake has to begin

SocketChannel channel = createSocketChannel();
SSLEngine sslEngine = createSSLEngine();
doHandShake(sslEngine,channel);


 private void doHandShake(SSLEngine sslEngine, SocketChannel socketChannel) throws Exception {
        System.out.println("Going to do Handshake");

        SSLSession session = sslEngine.getSession();

        ByteBuffer myAppData = ByteBuffer.allocate(session.getApplicationBufferSize());
        ByteBuffer peerAppData = ByteBuffer.allocate(session.getApplicationBufferSize());

        ByteBuffer myNetData = ByteBuffer.allocate(session.getPacketBufferSize());
        ByteBuffer peerNetData = ByteBuffer.allocate(session.getPacketBufferSize());

        sslEngine.beginHandshake();
        SSLEngineResult result;

        handshakeStatus = sslEngine.getHandshakeStatus();

        while (handshakeStatus != SSLEngineResult.HandshakeStatus.FINISHED &&
                handshakeStatus != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {


            switch (handshakeStatus) {
                case NEED_UNWRAP:
                    if (! (socketChannel.read(peerNetData) <0)) {
                        peerNetData.flip();
                        result = sslEngine.unwrap(peerNetData,peerAppData);
                        peerNetData.compact();

                        handshakeStatus = result.getHandshakeStatus();

                        switch (result.getStatus()) {
                            case OK:
                                break;
                        }

                    }

                    break;
                case NEED_WRAP:
                    myNetData.clear() ;// Empty the local network packet buffer
                    result = sslEngine.wrap(myAppData,myNetData);
                    handshakeStatus = result.getHandshakeStatus();
                    switch (result.getStatus()) {
                        case OK:
                            myNetData.flip();
                            while (myNetData.hasRemaining()) {
                                socketChannel.write(myNetData);
                            }
                    }
                    break;

                case NEED_TASK:
                    Runnable task  = sslEngine.getDelegatedTask();
                    if (null!=task) {
                        task.run();
                    }
                    handshakeStatus = sslEngine.getHandshakeStatus();
                    break;
            }


        }

完成handShake之后.您可以获取Principal对象

Once the handShake is done. you can get the Principal object

Principal principal = sslEngine.getSession().getPeerPrincipal();

            if (principal.getName().contains(SNI_HOST_NAME)) {
                System.out.println("available ... ");
            }else {
                System.out.println("Not available");
            }

这篇关于Java等同于OpenSSL s_client命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆