Java ftps连接,TrustManager说明(使用Filezilla服务器) [英] Java ftps connection, TrustManager explaination (using filezilla server)

查看:116
本文介绍了Java ftps连接,TrustManager说明(使用Filezilla服务器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个程序(显然是从网络上复制的,并根据我的需要进行了一些修改!),用于使用apache ftp api以及通过使用Filezilla服务器创建本地服务器来进行文件下载/上传。
一切正常。。问题是我没有得到我们必须创建信任管理器的部分。

I have written a program (obviously COPIED from the net, and modified it little according to my needs!) for file download/upload using apache ftp api and by creating a local server using Filezilla server. Everything is working FINE. The problem is I didn't get the part where we have to create a trust manager.

代码:

FTPSClient ftpsClient= null;
SSLContext sslContext = SSLContext.getInstance(protocol);
TrustManager tm = new X509TrustManager() {
    public X509Certificate[] getAcceptedIssuers() {
        System.out.println("getAcceptedIssuers------");
        return null;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] chain,
            String authType) throws CertificateException {
        // TODO Auto-generated method stub
        System.out.println("checkClientTrusted------");
    }

    @Override
    public void checkServerTrusted(X509Certificate[] chain,
            String authType) throws CertificateException {
        // TODO Auto-generated method stub
        System.out.println("checkServerTrusted------");
    }
};

    sslContext.init(null, new TrustManager[] { tm }, null);//new SecureRandom());
    ftpsClient = new FTPSClient(true, sslContext);

公共X509Certificate [] getAcceptedIssuers()根据文档返回的方法受信任用于对等身份验证的证书颁发机构的列表。但是在代码中,该方法返回null。

public X509Certificate[] getAcceptedIssuers() this method according to the documentation returns the list of certificate issuer authorities which are trusted for authentication of peers. But here in the code, the method is returning null.

此外,在Filezilla服务器中设置ftp的配置时,我必须创建

Also while setting the configuration for ftps in the Filezilla Server, I had to create a certificate.

由于我们没有通过或返回证书,因此我不明白为什么创建证书。还是服务器或库在内部处理它。有人可以向我详细说明这个问题。

Seeing all this I didn't get why the certificate was created as we are not passing or returning the certificate. Or does the server or library handles it internally. Can someone explain me thoroughly about this issue.

推荐答案

getAcceptedIssuers 仅适用于(Java)SSL / TLS服务器。

getAcceptedIssuers is used only for a (Java) SSL/TLS server. You are apparently "writing" a client.

在大多数情况下,SSL / TLS服务器需要证书和匹配的私钥。有些人将它们视为一件事,因为它们或多或少是一起创造的,但事实并非如此。通常,应该为每个服务器生成(创建)该对 ,但这并不总是必需的或必需的;我不特别了解FileZilla服务器。 SSL / TLS中有一些用于服务器的选项,它们不使用证书(或静态预生成的密钥)并且不进行身份验证,但是通常会禁用(或完全未实现)这些选项,因为实际上导致的连接经常被颠覆。相反,客户端也可以选择使用证书+私钥进行身份验证,通常称为双向或相互身份验证,但是很少使用。

An SSL/TLS server in most cases requires a certificate and matching private key. Some people treat these as one thing, because they are created more-or-less together, but they aren't. Typically that pair should be generated (created) for each server, but that isn't always necessary or required; I don't know for FileZilla server in particular. There are options in SSL/TLS for the server to not use a certificate (or "static" pregenerated key) and not be authenticated, but these are generally disabled (or completely unimplemented) because the resulting connections are in practice too often subverted. Conversely there are options for the client to also authenticate with a certificate+privatekey, often called "two-way" or "mutual" authentication, but they are rarely used.

回到通常情况,作为SSL / TLS握手的一部分,服务器提供一个证书,该证书标识由CA(或通常是多个CA的链)签名的服务器,客户端可以将其验证为受信任的服务器,并使用握手协议中的私钥有两种方式之一。无论哪种情况,都可以证明所到达的服务器是正确的服务器-或更确切地说,已经提供了证据来证明CA正确的服务器具有该密钥对,并且从那以后就不知道该密钥已被泄露。有关更多详细信息,请参见
https://security.stackexchange.com/questions/20803/how -does-ssl-work
https ://security.stackexchange.com/questions/1779/how-does-an-ssl-server-prove-its-identity
https://security.stackexchange.com/questions/6737/what-is -ssl证书,旨在证明和如何做

Returning to the usual case, as part of the SSL/TLS "handshake" the server presents a certificate which identifies the server signed by a CA (or usually a "chain" of multiple CAs) that the client can verify as trusted, and uses the privatekey in the handshake protocol in one of two ways. In either case this proves that the server reached is the right one -- or more exactly that evidence was provided to convince a CA the right server had that key(pair), and the key isn't known to have been compromised since. For more detail see
https://security.stackexchange.com/questions/20803/how-does-ssl-work
https://security.stackexchange.com/questions/1779/how-does-an-ssl-server-prove-its-identity
https://security.stackexchange.com/questions/6737/what-is-an-ssl-certificate-intended-to-prove-and-how-does-it-do-it

您的信任任何人 TrustManager绕过所有这些烦人的坚持都要求与正确的服务器通信。它说:实际上,我的数据是如此私人,必须加密以防止人们窃取它,但是我非常高兴将其发送到由可以访问我的网络或其中的某些东西的小偷运行的假服务器上,或经常使用的DNS。如果您(并且将始终)处于小型隔离网络中,则这可能是安全的-或至少,欺诈性服务器的风险不大于您的客户端或服务器本身被拥有的风险,从而确保连接的安全性无意义的。或者,如果数据实际上不是私有的,而您只是因为服务器需要它而使用SSL(这里可能不是真的),或者您喜欢自己进行额外的工作,那么安全性就不重要了。

Your "trust anybody" TrustManager bypasses all this annoying insistence on talking to the right server. It says in effect "my data is so private it must be encrypted to prevent people from stealing it, but I'm perfectly happy to send it to a fake server run by a thief who got access to my network, or something on it, or often the DNS I use". If you are (and always will be) on a small isolated network this may be safe -- or at least the risk of a fraudulent server is no greater than the risk your client or server is itself "0wned" thus rendering security of the connection meaningless. Or if the data is in fact not private and you're just using SSL because the server demands it (presumably not true here) or you enjoy making extra work for yourself, then security is unimportant.

编辑有关其他信息/问题:

EDIT for additional info/question:

好的,该文件包含PEM格式的 RSA PRIVATE KEY和证书正是我所说的服务器需要的:证书和匹配的私钥。 (很早以前就为PEM定义了BEGIN xxx加上5个破折号,base64数据和END xxx的格式,即使PEM本身已被放弃,该格式仍在使用。)对这些内容使用后缀.crt是不常见的,有点混乱是FileZilla选择的还是您?无论如何,客户端仅需要证书,并且不应该具有私钥,因此您确实需要提取某些东西,但是首先您需要查看所拥有的东西。

Okay, that file containing PEM-format 'RSA PRIVATE KEY' and 'CERTIFICATE' is exactly what I said a server needs: a certificate and matching private key. (The format with BEGIN xxx surrounded by 5 dashes, base64 data, then END xxx similarly was defined long ago for PEM and even though PEM itself has been abandoned the format is still used.) Using the suffix .crt for these contents is unusual and a bit confusing; did FileZilla choose that or did you? In any case, the client(s) need only a cert and should NOT have the privatekey so you do need to 'extract' something, but first you need to see what you have.

您拥有什么?除非FileZilla与您进行了CA交互,并且可能从您那里注意到了您的付款,否则该证书几乎肯定是自签名的 >,即使用其自己的密钥和名称进行签名,而不是使用CA的名称进行签名。通常,自签名证书不受广泛信任,并且需要管理更多工作,但是如果此环境仅适合您本人或像小型企业这样的少数群体,则自签名证书就足够了。证书中的主题名称是什么也很重要:对于正确检查的SSL / TLS连接,证书中的名称必须与您请求连接的名称相匹配;通常这是一个域名,但也可以是您不需要域名功能的IP地址(例如,您自己运行的服务器永远不会动)。还有其他选项可能在这里不适用。要查看所拥有的内容,请仅将证书部分(从破折号证书行通过破折号END行)复制到另一个文件,然后执行以下操作之一对其进行解码:

What do you have? Unless FileZilla interacted with a CA for you and probably got payment from you which you would have noticed, this certificate is almost certainly self-signed, that is, signed using its own key and name rather than signed by a CA under the CA's name. Selfsigned certs generally are not widely trusted and more work to manage, but if this environment is only for yourself or a limited group of people like a small business, a selfsigned cert can be adequate. It also matters what the "subject" name in the certificate is: for a properly checked SSL/TLS connection the name in the cert must match the name you request connection to; usually this is a domain name but it can be an IP address where you don't need the features of a domain name (e.g. a server you run yourself that never moves). There are also other options probably not applicable here. To see what you have, copy only the certificate part (from the dash-BEGIN CERTIFICATE line through and including the dash-END line) to another file and do one of the following to decode it:


  • 在Windows上以后缀 .cer 命名该文件,然后双击它以显示详细信息并查看颁发给:和颁发者:

  • on Windows name that file with suffix .cer and double-click it to display the details and look at Issued to: and Issued by:

在装有Java的系统上运行 keytool -printcert -file / path / to / that / file 并查看Owner:和Issuer:

on a system with Java installed run keytool -printcert -file /path/to/that/file and look at Owner: and Issuer:

在具有OpenSSL的系统上(Linux,其他可能)运行 openssl x509 -in / that / file -noout -text 并查看Subject:和Issuer:

on a system with OpenSSL (Linux, others maybe) run openssl x509 -in /that/file -noout -text and see Subject: and Issuer:

应使用什么?如果您的发卡行/作者和主题/所有者/彼此相等且与服务器名称匹配,良好的自签名证书。还要检查有效期(有效期,有效期至或不迟于有效期),以查看其是否会很快过期(临时证书)。此时,您有两个相互关联的选择。首先,是使用该证书还是其他证书:

What should you use? If you have issuer/by and subject/owner/to equal to each other and matching the name of your server, you have a good self-signed cert. Also check the validity date (valid to, valid until, or validity not-after) to see if it will expire (too) soon -- ad-hoc certs often do. At this point you have two interlinked choices to make. First, whether to use that cert or another:


  • 如果您拥有良好的自签名证书(正确的服务器名称和有效性),可以通过将其放在每个客户端的信任存储中来使用它。

  • if you have a good selfsigned cert (correct server name and validity) you can use it by putting it in the trust store of the/each client.

如果没有,但是您拥有(或获得)OpenSSL,则可以重新生成另一个具有您需要的名称和有效性的自签名证书,然后将那个放入服务器每个客户端的信任库中。

if not, but you have (or get) OpenSSL, you can re-generate another selfsigned cert which has whatever name and validity you need, and you put that in the server and the trust store of the/each client.

或代替任何自签名证书,您可以从Java信任的已建立CA(证书颁发机构)那里获得证书,例如Verisign,GoDaddy等。这通常每年花费一些钱,或者数量很少,并且要求您证明自己对证书中所需域名的权利(通过各种方式,例如发送给MX的电子邮件,DNS中的数据,Web服务器上的数据等)。此外,当今大多数CA都要求最好练习您的RSA密钥必须为2048位(或更多,但您不需要更多);我不知道FileZilla是否足够最新以生成该大小的密钥,如果不是,则必须先生成一个新密钥(使用openssl),然后才能继续从CA获取证书。 CA方法的优点是无需在每个客户端的信任库中添加任何内容。

or instead of any selfsigned cert you can get a cert from an established CA (Certificate Authority) that Java trusts, such as Verisign, GoDaddy etc. This usually costs some money every year or few, and requires you prove your "right" to the domain name you want in the certificate (by various means such as email to your MX, data in your DNS, data on webserver, etc.) In addition most CAs today enforce a best practice that your RSA key must be 2048 bits (or more, but you don't need more); I don't know if FileZilla is up-to-date enough to have generated the key that size and if not, you must generate a new key (with openssl) before you can proceed to get the cert from the CA. The advantage of the CA approach is nothing needs to be added to the trust store of the/each client.

如何信任它?,如前所述,在客户端,您无需为真正的CA方法做任何事情。但是对于使用Java SSL客户端(包括FTPS客户端)的
这种自签名方法,该自签名证书必须位于该客户端使用的信任库中,这里有几种方法:

How to trust it? On the client side, as noted, you don't need to do anything for the real-CA approach. But for the selfsigned approach, with a Java SSL client including an FTPS client, that selfsigned certificate must be in the truststore the client uses, and there are several methods here:


  • 使用JRE默认信任库,如果存在,则为文件 jssecacerts ,否则为文件<$ c $ JREHOME / lib / security 中的c> certs ,即位于任何目录下的子目录 lib / security JRE的安装位置。您正在使用的FTPSClient可能具有使用JRE默认 SSLContext 的方法,该方法使用默认的信任库,也可以将其传递给 SSLContext.getDefault() 。如果这是您唯一需要SSL连接的主机,则只需使用

    keytool -importcert -keystore jssecacerts -file / path / to将您的something.cer PEM文件从上面放入jssecacerts /something.cer 和密码 changeit (输入两次)。
    如果您需要来自同一JVM或JRE的其他SSL连接(尤其是到公共Internet),则首先将cacerts复制到jssecacerts,然后在-importcert上还指定 -alias myfilezilla (或唯一变体,仅字母和数字)。

  • use the JRE-default truststore, which is the file jssecacerts if it exists and otherwise the file cacerts in JREHOME/lib/security i.e. the subdirectory lib/security under whatever location your JRE is installed at. The FTPSClient you are using probably has a way to use the JRE default SSLContext which uses the default truststore, or you can pass it SSLContext.getDefault(). If this is the only host you need SSL connection to, just put your something.cer PEM file from above into jssecacerts with
    keytool -importcert -keystore jssecacerts -file /path/to/something.cer and password changeit (entered twice). If you need other SSL connections from the same JVM or JRE, especially to the public Internet, first copy cacerts to jssecacerts and on the -importcert also specify -alias myfilezilla (or a unique variant, letters and digits only).

覆盖默认的信任库。通过 keytool -importcert -keystore / path / to / mytrust -file /path/to/something.cer 创建一个包含(仅)证书的密钥库,然后将其放入/ path / to / mytrust与您的客户或与您的客户,或您(和其他用户)容易记住的某个位置与您的客户相关联。然后将系统属性 javax.net.ssl.trustStore 设置为JVM中的该文件。有几种方法可以执行此操作:始终在命令行上使用-D或在代码中调用 System.setProperty(n,v)(在第一次创建SSL套接字之前);在某些应用程序环境中,还有其他系统属性配置或管理功能。

override the default truststore. Create a keystore containing (only) your cert by keytool -importcert -keystore /path/to/mytrust -file /path/to/something.cer and either put that /path/to/mytrust in or with your client, or someplace that you (and any other users) will easily remember is associated with your client. Then set system property javax.net.ssl.trustStore to that file in your JVM. There are several ways to do that: always -D on the command line or call System.setProperty(n,v) in your code (before the first SSL socket creation); in some application environments there are other system-property configuration or management features.

编码您自己的信任库。创建一个 java.security.KeyStore 并使用包含您的证书的数据直接加载(通过 CertificateFactory .setCertificateEntry ),或者通过加载先前使用上述keytool创建的文件;然后使用您的密钥库创建一个真实的(非空位) javax.net.ssl.TrustManager .init ;然后以与现在相同的方式在您的 SSLContext 中使用该 TrustManager 。这比较复杂,如果上面的两个简单选项都对您有用,我不建议这样做。

code your own truststore. Create a java.security.KeyStore and load it with data containing your cert -- either directly (read the cert through a CertificateFactory and .setCertificateEntry) or by loading a file that you previously created with keytool as above; then create a real (not nobbled) javax.net.ssl.TrustManager and .init it with your keystore; then use that TrustManager in your SSLContext in the same way you have now. This is more complicated and I don't recommend it if either of the simpler options above works for you.

这篇关于Java ftps连接,TrustManager说明(使用Filezilla服务器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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