4

概要: Salesforce.com は最近、サンドボックス インスタンス (test.salesforce.com) の TLSv1 を無効にし、インバウンド リクエストとアウトバウンド リクエストの両方の API 統合に対して TLSv1.1 以降のみをサポートできます。

JDK 7.0 で Java Axis1.0 クライアント コードを使用して、(Web サービス SOAP 経由で) salesforce.com に接続しています。「UNSUPPORTED_CLIENT: この組織では TLS 1.0 が無効になっています。https を使用して Salesforce に接続する場合は、TLS 1.1 以上を使用してください。」という例外が発生します。 With Java7.0 Supported Protocols:SSLv2Hello, SSLv3, TLSv1, TLSv1.1, TLSv1.2 Enabled Protocols: TLSv1

Java8.0 で、java8 クライアントで salesforce.com に接続しようとすると、接続に成功します。

サポートされているプロトコル: SSLv2Hello、SSLv3、TLSv1、TLSv1.1、TLSv1.2 有効なプロトコル: TLSv1、TLSv1.1、TLSv1.2`

アプリケーションがJava 7を使用しているため、Java 7を使用する必要があります。VM引数を設定しようとしました: -Dhttps.protocols=TLSv1.1,TLSv1.2 -Ddeployment.security.SSLv2Hello=false -Ddeployment.security.SSLv3=false -Ddeployment.security.TLSv1=false -Ddeployment.security.TLSv1.1 =true -Ddeployment.security.TLSv1.2=true" しかし成功しません。

Java7 で TLSv1.1 を有効にするための設定を見つけるのを手伝ってもらえますか?

4

3 に答える 3

5

解決策を見つけました:

カスタム JSSESocketFactory (Java Web サービス Axis1.0 クライアントを使用しているため) と AxisProperties 設定を作成する必要がありました。

何かのようなもの、

public class TLSSocketSecureFactory extends JSSESocketFactory {

private final String TLS_VERSION_1_1 = "TLSv1.1";
private final String TLS_VERSION_1_2 = "TLSv1.2";

public TLSSocketSecureFactory(@SuppressWarnings("rawtypes") Hashtable attributes) {
super(attributes);
}

@Override
protected void initFactory() throws IOException {
SSLContext context;
try {
  context = SSLContext.getInstance(TLS_VERSION_1_1);
  context.init(null, null, null);
  sslFactory = context.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
  //printstacktrace or throw IOException
}
}

@Override
public Socket create(String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL) throws Exception {
if (sslFactory == null) {
  initFactory();
}
Socket s = super.create(host, port, otherHeaders, useFullURL);
((SSLSocket) s).setEnabledProtocols(new String[] {TLS_VERSION_1_1, TLS_VERSION_1_2 });
return s;
}
}

AxisProperties.setProperty("axis.socketSecureFactory",TLSSocketSecureFactory.class.getCanonicalName());

これは、JDK7 でのみ必要です。アプリケーションがJDK8に移行される場合、このクラスは不要です。Java8 では、TLSv1.1 および TLS1.2 がデフォルトで有効になっています。

注: サーバーで VM 構成を設定しても、Axis Java クライアントの場合は役に立ちません。

于 2016-07-02T00:29:31.680 に答える
2

上記のソリューションは、Axis トランスポートがデフォルトの HTTPSender である場合にうまく機能します。また、新しいソケット ファクトリは AxisProperties だけでなく、次のようにコマンド ラインで渡すことができるシステム プロパティにも置き換えることができることを知っておくと便利です。

-Dorg.apache.axis.components.net.SecureSocketFactory=your.package.TLSv12JSSESocketFactory

私の TLSv12JSSESocketFactory のコードは次のとおりです。

package your.package;

import java.util.Hashtable;
import java.io.IOException;
import java.net.Socket;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import org.apache.axis.components.net.JSSESocketFactory;
import org.apache.axis.components.net.BooleanHolder;

public class TLSv12JSSESocketFactory extends JSSESocketFactory {

    private final String TLS_VERSION_1_2 = "TLSv1.2";

    public TLSv12JSSESocketFactory( @SuppressWarnings("rawtypes") Hashtable attributes ) {
        super(attributes);
    }

    @Override
    protected void initFactory() throws IOException {
        SSLContext context;
        try {
            context = SSLContext.getInstance( TLS_VERSION_1_2 );
            context.init( null, null, null );
            sslFactory = context.getSocketFactory();
        } catch ( Exception e ) {
            throw new IOException( "Could not init SSL factory with TLS context: " + TLS_VERSION_1_2, e );
        }
    }

    @Override
    public Socket create( String host, int port, StringBuffer otherHeaders, BooleanHolder useFullURL ) throws Exception {

        Socket s = super.create( host, port, otherHeaders, useFullURL );
        ((SSLSocket) s).setEnabledProtocols( new String[] { TLS_VERSION_1_2 } );

        return s;
    }
}

私の場合、トランスポートとして Apache Commons HttpClient を使用して Axis 1.4 を変更する必要がありました。これには、SecureProtocolSocketFactory インターフェイスを実装するクラスの作成が含まれていました。これが私のコードです:

package your.package;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.ssl.SSLSocket;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;


public class TLSv12HttpsSocketFactory implements SecureProtocolSocketFactory
{
    private static final String TLS_VERSION_1_2 = "TLSv1.2";
    private final SecureProtocolSocketFactory base;

    public TLSv12HttpsSocketFactory( ProtocolSocketFactory base )
    {
        if ( base == null || !(base instanceof SecureProtocolSocketFactory) ) throw new IllegalArgumentException();
        this.base = (SecureProtocolSocketFactory) base;
    }

    private Socket acceptOnlyTLS12( Socket socket )
    {
        if ( socket != null && (socket instanceof SSLSocket) ) {
            ((SSLSocket) socket).setEnabledProtocols( new String[] { TLS_VERSION_1_2 } );
        }

        return socket;
    }

    @Override
    public Socket createSocket( String host, int port ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port) );
    }

    @Override
    public Socket createSocket( String host, int port, InetAddress localAddress, int localPort ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port, localAddress, localPort) );
    }

    @Override
    public Socket createSocket( String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(host, port, localAddress, localPort, params) );
    }

    @Override
    public Socket createSocket( Socket socket, String host, int port, boolean autoClose ) throws IOException
    {
        return acceptOnlyTLS12( base.createSocket(socket, host, port, autoClose) );
    }
}

しかし、次のように org.apache.axis.transport.http.CommonsHTTPSender クラス (コンパイル時にいくつかのクラス ファイルを生成する) も変更する必要がありました。

// import the new socket factory
import your.package.TLSv12HttpsSocketFactory;
...
// add this at the end of the initialize() method
// setup to our custom TLSv1.2 socket factory
String scheme = "https";
Protocol baseHttps = Protocol.getProtocol( scheme );
int defaultPort = baseHttps.getDefaultPort();

ProtocolSocketFactory baseFactory = baseHttps.getSocketFactory();
ProtocolSocketFactory customFactory = new TLSv12HttpsSocketFactory( baseFactory );

Protocol customHttps = new Protocol( scheme, customFactory, defaultPort );
Protocol.registerProtocol( scheme, customHttps );
于 2018-02-07T18:57:44.770 に答える