Anricx

Anricx 查看完整档案

成都编辑  |  填写毕业院校  |  填写所在公司/组织 github.com/anricx 编辑
编辑

全栈工程师

个人动态

Anricx 回答了问题 · 2019-03-04

springmvc 只更新部分字段,接收参数时需要重新建一个实体类吗?

更新的时候判断不等于null的执行更新动作,可以用User接收参数啊,字段不要有默认值即可。
前端不传递那个字段,则不会有值。自然update的时候不会更新。

关注 2 回答 1

Anricx 回答了问题 · 2019-02-26

mac下使用ssh连接服务器或者GitHub

你是否吧你自己的公钥配置到github? 是否配置了linux的.ssh/authorized_keys ?

关注 3 回答 1

Anricx 评论了文章 · 2019-02-01

彻底搞清楚SSL/TLS

1 TLS/SSL的前世今生

SSL(Secure Sockets Layer)最初由Netscape定义, 分别有SSLv2和SSLv3两个版本(SSLv1未曾对外发布); 在SSLv3之后SSL重命名为TLS。

TLS(Transport Layer Security)版本从TLSv1.0开始, TLSv1.0是在SSLv3的基础上升级而来。

协议时间建议说明
SSLv1//实际从未公开发布。
SSLv21995弃用IETF已于2011年弃用。
SSLv31996弃用IETF已于2015年弃用。
TLSv1.01999兼容-
TLSv1.12006兼容-
TLSv1.22008主推目前最新可用版本
TLSv1.3//2016开始草案制定

多年以来已弃用的SSL协议也暴露出了一些高危漏洞(例如: POODLE, DROWN); 因此建议服务器禁用SSL3.0及SSL2.0, 只启用TLS协议。

2 证书如何工作

SSL/TLS使用证书来实现对数据的加密传输以及身份认证。

3 TLS握手过程

TLS握手过程

3.1 导致握手失败的一些原因

  • 两边协议版本不兼容
  • 两边加密算法无匹配项

更多关于如何优雅处理HTTPS中的证书问题可参考这里

附录

[1] RFC6176 - Prohibiting Secure Sockets Layer (SSL) Version 2.0
https://tools.ietf.org/html/r...
[2] RFC7568 - Deprecating Secure Sockets Layer Version 3.0
https://tools.ietf.org/html/r...
[3] RFC2246 - The TLS Protocol Version 1.0
https://tools.ietf.org/html/r...
[4] RFC4346 - The Transport Layer Security (TLS) Protocol Version 1.1
https://tools.ietf.org/html/r...
[5] RFC5246 - The Transport Layer Security (TLS) Protocol Version 1.2
https://tools.ietf.org/html/r...
[6] RFC2246 - The TLS Protocol Version 1.0
https://tools.ietf.org/html/r...
[7] RFC4346 - The Transport Layer Security (TLS) Protocol Version 1.1
https://tools.ietf.org/html/r...
[8] RFC5246 - The Transport Layer Security (TLS) Protocol Version 1.2
https://tools.ietf.org/html/r...
[9] The Transport Layer Security (TLS) Protocol Version 1.3
https://tools.ietf.org/html/d...
[10] SSL and TLS Protocols
https://wiki.openssl.org/inde...

查看原文

Anricx 发布了文章 · 2019-01-30

彻底搞清楚SSL/TLS

1 TLS/SSL的前世今生

SSL(Secure Sockets Layer)最初由Netscape定义, 分别有SSLv2和SSLv3两个版本(SSLv1未曾对外发布); 在SSLv3之后SSL重命名为TLS。

TLS(Transport Layer Security)版本从TLSv1.0开始, TLSv1.0是在SSLv3的基础上升级而来。

协议时间建议说明
SSLv1//实际从未公开发布。
SSLv21995弃用IETF已于2011年弃用。
SSLv31996弃用IETF已于2015年弃用。
TLSv1.01999兼容-
TLSv1.12006兼容-
TLSv1.22008主推目前最新可用版本
TLSv1.3//2016开始草案制定

多年以来已弃用的SSL协议也暴露出了一些高危漏洞(例如: POODLE, DROWN); 因此建议服务器禁用SSL3.0及SSL2.0, 只启用TLS协议。

2 证书如何工作

SSL/TLS使用证书来实现对数据的加密传输以及身份认证。

3 TLS握手过程

TLS握手过程

3.1 导致握手失败的一些原因

  • 两边协议版本不兼容
  • 两边加密算法无匹配项

更多关于如何优雅处理HTTPS中的证书问题可参考这里

附录

[1] RFC6176 - Prohibiting Secure Sockets Layer (SSL) Version 2.0
https://tools.ietf.org/html/r...
[2] RFC7568 - Deprecating Secure Sockets Layer Version 3.0
https://tools.ietf.org/html/r...
[3] RFC2246 - The TLS Protocol Version 1.0
https://tools.ietf.org/html/r...
[4] RFC4346 - The Transport Layer Security (TLS) Protocol Version 1.1
https://tools.ietf.org/html/r...
[5] RFC5246 - The Transport Layer Security (TLS) Protocol Version 1.2
https://tools.ietf.org/html/r...
[6] RFC2246 - The TLS Protocol Version 1.0
https://tools.ietf.org/html/r...
[7] RFC4346 - The Transport Layer Security (TLS) Protocol Version 1.1
https://tools.ietf.org/html/r...
[8] RFC5246 - The Transport Layer Security (TLS) Protocol Version 1.2
https://tools.ietf.org/html/r...
[9] The Transport Layer Security (TLS) Protocol Version 1.3
https://tools.ietf.org/html/d...
[10] SSL and TLS Protocols
https://wiki.openssl.org/inde...

查看原文

赞 7 收藏 7 评论 2

Anricx 发布了文章 · 2019-01-29

优雅处理HTTPS中的证书问题

Java中HTTPS会遇到的问题

  • 访问自签名的HTTPS网站
  • 高版本JRE访问SSLv3/SSLv2站点
  • 一些银行接口需要加载keystore的场景

* 如果要了解SSL历史也可以看看这篇文章

1 访问自签名的HTTPS网站

常常看到的回答是直接通过信任所有来支持, 这不优雅; 优雅的操作应该:

  • 下载服务端的CA证书
# 方式1: 导出DER格式的证书
# 这里需要通过指定servername来保证导出的证书和当前域名匹配
openssl s_client -showcerts -connect self-signed.badssl.com:443 -servername self-signed.badssl.com </dev/null 2>/dev/null|openssl x509 -outform der >self-signed.badssl.com.der
  • 代码中通过加载服务端证书后通过自定义SSLContext访问目标服务器:
private SSLContext sslContext(File certificateFile, String certificateType) {

    InputStream inputStream = null;
    try {
        inputStream = new FileInputStream(certificateFile);
        CertificateFactory cf = CertificateFactory.getInstance(certificateType);
        Certificate certificate = cf.generateCertificate(inputStream);
        System.out.println("ca=" + ((X509Certificate) certificate).getSubjectDN());
        String alias = ((X509Certificate) certificate).getSubjectDN().toString();

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry(alias, certificate);

        // Create a KeyStore containing our trusted CAs
        SSLContext sslcontext = SSLContexts.custom()
                .loadTrustMaterial(keyStore, new TrustSelfSignedStrategy())
                .build();
        return sslcontext;
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (CertificateException e) {
        throw new RuntimeException(e);
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    } catch (KeyStoreException e) {
        throw new RuntimeException(e);
    } catch (KeyManagementException e) {
        throw new RuntimeException(e);
    } finally {
        if (inputStream != null) try { inputStream.close(); } catch (IOException e) { }
    }
}

@Test
public void testSelfSign() throws IOException {
    File certFile = ResourceUtils.getFile(this.getClass().getResource("/root.cer"));

    CloseableHttpClient httpclient = HttpClients.custom()
            .setSSLContext(sslContext(certFile, "X.509"))  //
            .build();

    String body = Executor.newInstance(httpclient).execute(Request
            .Get("https://self-signed.badssl.com/"))
            .returnContent()
            .asString();
    System.out.println(body);
}

2 高版本JRE访问SSLv3/SSLv2站点

通常你得到的答案是通过修改${JRE_HOME}/lib/security/java.security目录下某些配置项来取消高版本SDK对某些不安全SSL协议版本或算法的限制。

各版本对SSL的支持情况

JDK8JDK7JDK6
TLS ProtocolsTLSv1.2 (default)<br/>TLSv1.1<br/>TLSv1<br/>SSLv3TLSv1.2<br/>TLSv1.1<br/>TLSv1 (default)<br/>SSLv3TLS v1.1 (JDK 6 update 111 and above)<br/>TLSv1 (default)<br/>SSLv3
JSSE Ciphers:Ciphers in JDK 8Ciphers in JDK 7Ciphers in JDK 6
Reference:JDK 8 JSSEJDK 7 JSSEJDK 6 JSSE
Java Cryptography Extension, Unlimited Strength (explained later)JCE for JDK 8JCE for JDK 7JCE for JDK 6

* 在2015年1月发布的升级补丁中也已经禁用对SSLv3的支持。

所以为什么会出现在某些高版本无法访问某些HTTPS站点的原因就是由于有以下可能:

  • 服务端支持对SSL版本在本地JRE已经被禁用, 例如服务端只支持SSLv3而JDK已经默认关闭了对SSLv3的支持。
  • 服务端使用的JSSE Ciphers和本地支持的JSSE Ciphers没有共同项导致无法正常选择加密算法。

2.1 确认当前JRE启用SSL协议

@Test
public void sslSupport() throws IOException {
    SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    SSLSocket soc = (SSLSocket) factory.createSocket();

    // Returns the names of the protocol versions which are
    // currently enabled for use on this connection.
    String[] protocols = soc.getEnabledProtocols();

    System.out.println("Enabled protocols:");
    for (String s : protocols) {
        System.out.println(s);
    }
}

输出:

Enabled protocols:
TLSv1
TLSv1.1
TLSv1.2

2.2 确认当前JRE启用CipherSutes

String[] cipers = soc.getEnabledCipherSuites();
System.out.println("Enabled CipherSutes:");
for (String s : cipers) {
    System.out.println(s);
}

输出

Enabled CipherSutes:
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
TLS_EMPTY_RENEGOTIATION_INFO_SCSV

2.3 检查服务器支持的SSL协议

这里我推荐使用nmap检测:

nmap --script ssl-enum-ciphers -p 443 badssl.com

输出:

Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-01 22:26 CST
Nmap scan report for badssl.com (104.154.89.105)
Host is up (0.32s latency).
rDNS record for 104.154.89.105: 105.89.154.104.bc.googleusercontent.com

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 2048) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256r1) - C
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (dh 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|_  least strength: C

Nmap done: 1 IP address (1 host up) scanned in 39.91 seconds

根据输出可以看到badssl.com同时支持TLSv1.0TLSv1.1以及TLSv1.2, 同时也可以看到当前对应协议支持的加密算法。

2.4 解决方案

JRE在${JRE_HOME}/lib/security/java.security配置了一些算法的配置, 例如本地我的${JRE_HOME}/lib/security/java.security配置内容为:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, 3DES_EDE_CBC

表示当前JRE要禁用SSLv3协议以及RC4DES等算法。

当然我们可以通过手动修改该文件来取消这些限制来达到我们对目的, 但这样程序在部署到新环境就可能不能正常运行, 不优雅! 优雅对操作如下:

  • 根据协议版本动态对JRE对设置取消设置, 在JRE中管理相关SSL协议以及算法的配置项主要是jdk.tls.disabledAlgorithms
// 取消当前运行环境对SSLv3、RC4、DES以及3DES_EDE_CBC的禁用限制
static {
    String disabledAlgorithms = Security.getProperty("jdk.tls.disabledAlgorithms");
    HashSet<String> keys = Sets.newHashSet(disabledAlgorithms.split(", +"));
    if (keys.contains("SSLv3")) keys.remove("SSLv3");
    if (keys.contains("RC4")) keys.remove("RC4");
    if (keys.contains("DES")) keys.remove("DES");
    if (keys.contains("3DES_EDE_CBC")) keys.remove("3DES_EDE_CBC");

    Security.setProperty("jdk.tls.disabledAlgorithms", StringUtils.join(keys, ", "));
    log.debug("SECURITY PROPERTY UPDATED \"jdk.tls.disabledAlgorithms\" = " + Security.getProperty("jdk.tls.disabledAlgorithms"));
}
  • 自定义SSLConnectionSocketFactory兼容对低版本协议对支持, 突破JRE默认限制。
// Allow SSLv3, TLSv1, TLSv1.2 protocol only
SSLConnectionSocketFactory sslConnectionSocketFactory =  new SSLConnectionSocketFactory(
        sslContext,
        new String[] { "SSLv3", "TLSv1", "TLSv1.2"},
        null,
        NoopHostnameVerifier.INSTANCE);

至此你就可以完美且优雅的解决这个问题。

附录

[1] HTTPS
https://en.wikipedia.org/wiki...
[2] Obtain a Certificate from Server
https://ldapwiki.com/wiki/Obt...
[3] Transport Level Security (TLS) and Java
http://www.ateam-oracle.com/t...
[4] Diagnosing TLS, SSL, and HTTPS
https://blogs.oracle.com/java...

查看原文

赞 3 收藏 2 评论 1

Anricx 回答了问题 · 2019-01-02

Class.forName异常找不到类,但是参数是包名+类名

  1. 确定待加载待类是否在classpath下;
  2. 如果不在你可以设置到classpath下或者通过classloader动态加载。

关注 2 回答 1

Anricx 回答了问题 · 2018-03-21

php 图片加水印

你需要计算一个缩放比例,根据传入图片的大小,缩放你的水印图片,哈哈。
你想你的水印固定大小,图片大小不同,那么当然贴上去的效果不同。

关注 2 回答 1

Anricx 回答了问题 · 2018-03-16

用一个域名绑定了两个IP地址

nslookup看看域名解析。

关注 2 回答 1

Anricx 回答了问题 · 2018-03-04

SpringBoot:请教@PostConstruct为什么会被执行两次

@Configuration会创建一个Bean实例;
@Bean会再创建一个Bean实例;
所以就导致创建了两个对象,故@PostConstruct被执行了两次。

关注 2 回答 1

Anricx 回答了问题 · 2018-03-04

jwt 中的 secret 是起什么作用?

JWT的原理就是服务端根据secret生成token,当然secret只有服务器自己才知道是多少,也就让token只能是由服务端签发;

看看
http://blog.csdn.net/u0112771...

关注 2 回答 1

认证与成就

  • 获得 48 次点赞
  • 获得 5 枚徽章 获得 0 枚金徽章, 获得 1 枚银徽章, 获得 4 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2018-01-27
个人主页被 1.3k 人浏览