使用 HttpsURLConnection 时如何覆盖 Android 发送到服务器的密码列表?

2024-05-01

在 TLS 协商期间,客户端将受支持的密码列表发送到服务器,服务器选择一个,然后开始加密。当我使用时,我想更改 Android 发送到服务器的密码列表HttpsURLConnection用于沟通。

我知道我可以使用setSSLSocketFactory on the HttpsURLConnection对象将其设置为使用SSLSocketFactory。当我想更改使用的信任管理器等时,这很有用SSLSocket由返回SSLSocketFactory.

我知道一般来说这个密码套件列表可以使用SSLParameters对象并将其传递给SSlsocket or SSLEngine对象使用它们提供的方法。

BUT the SSLSocketFactory好像没有公开这样的方法!

我找不到改变的方法SSLParameters归来的SSLSocket由创建的对象SSLSocketFactory我传递给HttpsURLConnection.

该怎么办?

我想这也与 Java 相关,而不仅仅是 Android。也许有一种面向对象的方法可以做到这一点(例如扩展SSLSocketFactory并将其提供给HttpsURLConnection?)


这段代码有点生涩。请小心使用。

public class PreferredCipherSuiteSSLSocketFactory extends SSLSocketFactory {


private static final String PREFERRED_CIPHER_SUITE = "TLS_RSA_WITH_AES_128_CBC_SHA";

private final SSLSocketFactory delegate;

public PreferredCipherSuiteSSLSocketFactory(SSLSocketFactory delegate) {

    this.delegate = delegate;
}

@Override
public String[] getDefaultCipherSuites() {

    return setupPreferredDefaultCipherSuites(this.delegate);
}

@Override
public String[] getSupportedCipherSuites() {

    return setupPreferredSupportedCipherSuites(this.delegate);
}

@Override
public Socket createSocket(String arg0, int arg1) throws IOException,
        UnknownHostException {

    Socket socket = this.delegate.createSocket(arg0, arg1);
    String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
    ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);

    return socket;
}

@Override
public Socket createSocket(InetAddress arg0, int arg1) throws IOException {

    Socket socket = this.delegate.createSocket(arg0, arg1);
    String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
    ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);

    return socket;
}

@Override
public Socket createSocket(Socket arg0, String arg1, int arg2, boolean arg3)
        throws IOException {

    Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
    String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
    ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);

    return socket;
}

@Override
public Socket createSocket(String arg0, int arg1, InetAddress arg2, int arg3)
        throws IOException, UnknownHostException {

    Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
    String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
    ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);

    return socket;
}

@Override
public Socket createSocket(InetAddress arg0, int arg1, InetAddress arg2,
        int arg3) throws IOException {

    Socket socket = this.delegate.createSocket(arg0, arg1, arg2, arg3);
    String[] cipherSuites = setupPreferredDefaultCipherSuites(delegate);
    ((SSLSocket)socket).setEnabledCipherSuites(cipherSuites);

    return socket;
}

private static String[] setupPreferredDefaultCipherSuites(SSLSocketFactory sslSocketFactory) {

    String[] defaultCipherSuites = sslSocketFactory.getDefaultCipherSuites();

    ArrayList<String> suitesList = new ArrayList<String>(Arrays.asList(defaultCipherSuites));
    suitesList.remove(PREFERRED_CIPHER_SUITE);
    suitesList.add(0, PREFERRED_CIPHER_SUITE);

    return suitesList.toArray(new String[suitesList.size()]);
}

private static String[] setupPreferredSupportedCipherSuites(SSLSocketFactory sslSocketFactory) {

    String[] supportedCipherSuites = sslSocketFactory.getSupportedCipherSuites();

    ArrayList<String> suitesList = new ArrayList<String>(Arrays.asList(supportedCipherSuites));
    suitesList.remove(PREFERRED_CIPHER_SUITE);
    suitesList.add(0, PREFERRED_CIPHER_SUITE);

    return suitesList.toArray(new String[suitesList.size()]);
}
}

当你想使用它的时候。

            HttpsURLConnection connection = (HttpsURLConnection) (new URL(url))
                .openConnection();
        SSLContext context = SSLContext.getInstance("TLS");
        TrustManager tm[] = {new SSLPinningTrustManager()};
        context.init(null, tm, null);
        SSLSocketFactory preferredCipherSuiteSSLSocketFactory = new PreferredCipherSuiteSSLSocketFactory(context.getSocketFactory());
        connection.setSSLSocketFactory(preferredCipherSuiteSSLSocketFactory);
                    connection.connect();

感谢您。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 HttpsURLConnection 时如何覆盖 Android 发送到服务器的密码列表? 的相关文章

  • “传输协议线程失败” – “套接字为 EOF”,使用 Java 进行 J2SSH 连接

    我正在尝试通过我的 Java 代码建立 SSH 连接 但遇到异常 我通过 Putty Winscp 工具测试了我的连接 它工作正常 问题出在我的 Java 代码上 SEVERE The Transport Protocol thread f
  • 如何制作一个向用户显示图像而不是文本的下拉列表?

    ObjectChoiceField 字段满足我的所有要求 但它并不漂亮 这就是我所拥有的 String pets Dog Cat Duck ObjectChoiceField dd new ObjectChoiceField My Pet
  • 当我单击 GridView 项时返回 ImageView 实例

    当我点击GridView项时如何返回ImageView实例 我为 ItemClick 创建自定义绑定事件 public class ItemClickSquareBinding MvxBaseAndroidTargetBinding pri
  • 如果从超链接打开,应用程序将启动两次

    我正在开发一个应用程序 可以从多个地方启动 例如日历中的超链接 我在以下场景中面临问题 如果应用程序已启动并在后台运行 并且用户单击本机日历中的事件 超链接来启动应用程序 我的应用程序作为新实例启动两次 在正在运行的应用程序列表中 我可以看
  • Textview 第一次点击时为空,但第二次点击时更新

    它是使用兼容性包的小型 Android 2 2 测试应用程序 我正在尝试更新列表项选择上另一个活动的另一个片段上的文本视图 但问题是 每次第一次单击都会返回空指针异常 并且只有在第二次尝试时 其文本才会更改 我想知道为什么会发生这种情况以及
  • 如何在调整大小时更改 JLabel 字体大小以填充 JPanel 可用空间?

    这里有一个类似的问题 如何更改 JLabel 的字体大小以获取最大大小 https stackoverflow com questions 2715118 how to change the size of the font of a jl
  • 以编程方式卸载 Android 应用程序

    我希望能够允许我的用户从我的应用程序中卸载应用程序 就像 Google Play 商店允许其用户一样 请下图 主要问题是如何定义一个按钮 按下它我们可以通过提供包名称或其他一些信息来卸载应用程序 就像图像上的卸载按钮一样 try Inten
  • XML 文档结构必须在同一实体内开始和结束

    我是 eclipse 的新手 我刚刚开始编写一些代码 实际上只是从网站复制并粘贴 谁能帮我解决这个问题 错误出现在最后一行
  • AWS Lambda 和 S3 - 上传的 pdf 文件为空/损坏

    我有一个 Spring 应用程序 在 AWS Lambda 上运行 它获取文件并将其上传到 AWS S3 Spring控制器发送一个MultipartFile到我的方法 使用 Amazon API Gateway 将其上传到 AWS S3
  • CTRL-C 在 Python 中的行为有所不同

    I ve recently started learning Python long time Java programmer here and currently in the process of writing some simple
  • Android 中可以导入 java.rmi.* 吗?

    我的分布式系统课程中有一个项目 我们必须在我们的项目中使用 java rmi 而且我知道由于 dalvik VM 问题 android 不提供这个库 所以我只是想问是否可以在 Android 上使用这些库 Thanks Android 不支
  • 为什么 writeObject 抛出 java.io.NotSerializedException 以及如何修复它?

    我有这个异常 我不明白为什么会抛出它 或者我应该如何处理它 try os writeObject element catch IOException e e printStackTrace Where element is a Transf
  • 告诉 JAXB 使用注释将 解组为 Date 类

    将 JAXB 与 Java First 一起使用时 类型的字段 属性java util Date编组和解编为xs dateTime一切都按预期进行 但是如果字段 属性的类型是Object JAXB 解组xs dateTimeto XMLGr
  • SSLHandShakeException 没有适当的协议

    我最近向我的网站添加了 SSL 可以通过 https 访问它 现在 当我的 java 应用程序尝试向我的网站发出请求并使用缓冲读取器从中读取时 它会生成此堆栈跟踪 我没有使用自签名证书 该证书来自 Namecheap 它使用 COMODO
  • 不幸的是应用程序已在 Android 模拟器中停止

    我是 Android 新手 正在尝试一些小应用程序 例如 Compass 当我在模拟器中运行应用程序时 它会给出消息Unfortunately Compass has Stopped 我没有编译时错误 我该如何解决这个问题 是什么原因造成的
  • 如何使用 Java 1.4 和 SAX 将任意数据编码为 XML?

    我们使用 SAX 来解析 XML 因为它不需要将整个 XML 文档读入内存来解析单个值 我读过很多文章 坚持认为 SAX 只能用于解析 解码 XML 而不能创建它 这是真的 不 这不是真的 您可以使用类似于以下内容的方式将 XML 编码为
  • 从 SSLv3 迁移到 TLSv1

    对于 POODLE SSLv3 现已在服务器上禁用 客户端软件是在 NET 2 0 中开发的 并提供 TLSv1 作为唯一的替代方案 我有权并有能力更改客户端应用程序和服务器配置 ServicePointManager SecurityPr
  • 运行外部进程的非阻塞线程

    我创建了一个 Java GUI 应用程序 它充当许多低级外部进程的包装器 该实用程序按原样运行 但迫切需要一项重大改进 我希望我的外部进程以非阻塞方式运行 这将允许我并行服务其他请求 简而言之 我希望能够在生成数据时处理来自外部进程的数据
  • Android 布局以 开头 [重复]

    这个问题在这里已经有答案了 我是 Android 应用程序开发的初学者 我的问题很简单 我似乎无法确定布局文件夹中的 xml 文件是否应以以下开头 当我制作一个入门项目时 它不存在 但我也在读一本书 上面说它应该在那里 正确的方法是什么 嗯
  • Flutter 中 Android RecyclerView.SCROLL STATE IDLE 的等价物是什么

    Android 给出的滚动状态如下RecyclerView SCROLL STATE IDLE它告诉用户何时停止滚动 我找不到任何选择在颤动中Pageview or ListView滚动监听器 我的问题 我需要检测 PageView 中的向

随机推荐