I am trying to get a mutual authentication request to work on android. I am testing against my own server so I have a self signed CA and client certificate.
我正在尝试在android上获得一个相互验证的请求。我正在测试我自己的服务器,所以我有一个自签名CA和客户端证书。
So I will have to allow for untrusted server cert.
因此,我将不得不允许不受信任的服务器证书。
Here is what I am doing:
下面是我所做的:
KeyStore clientCertificate = KeyStore.getInstance("PKCS12");
InputStream client_inputStream = getResources().openRawResource(R.raw.client);
clientCertificate.load(client_inputStream, "password".toCharArray());
new SSLRequest(clientCertificate).execute();
Then the AsyncTask to perform the request:
然后AsyncTask执行请求:
class SSLRequest extends AsyncTask<Void, Void, Void> {
private Exception exception;
private KeyStore clientCertificate;
public SSLRequest(KeyStore clientCertificate) {
this.clientCertificate = clientCertificate;
}
protected Void doInBackground(Void... params) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new SSLSocketFactory(clientCertificate, null, trustStore);
HttpParams httpParameters = new BasicHttpParams();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", sf, 443));
ClientConnectionManager cm = new SingleClientConnManager(httpParameters, schemeRegistry);
DefaultHttpClient httpClient = new DefaultHttpClient(cm, httpParameters);
HttpGet request = new HttpGet("https://myserver.com/some.json");
HttpResponse response = httpClient.execute(request);
response.getEntity().consumeContent();
} catch (Exception e) {
this.exception = e;
}
return null;
}
protected void onPostExecute(Void params) {
if (exception != null) {
status.setText("Error making SSL handshake");
} else {
status.setText("Successful SSL handshake");
}
}
}
I have tested this request in a browser and in an iOS client but I cannot get it to work in Android.
我在浏览器和iOS客户端测试过这个请求,但我无法让它在Android中运行。
I think this is the right way to allow untrusted server certificates:
我认为这是允许不受信任的服务器证书的正确方法:
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new SSLSocketFactory(clientCertificate, "password", trustStore);
Not sure why I am getting:
不知道为什么会这样:
javax.net.ssl.SSLPeerUnverifiedException
javax.net.ssl.SSLPeerUnverifiedException
EDIT:
编辑:
I had to add my own SSLSocketFactory to trust the self signed server cert:
我必须添加自己的SSLSocketFactory来信任自签名服务器证书:
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore keystore, String keystorePassword, KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(keystore, keystorePassword, truststore);
TrustManager trustManager = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {trustManager}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
Once I use that I get the following:
一旦我使用,我得到如下:
javax.net.ssl.SSLHandshakeException: Handshake failed
javax.net.ssl.SSLHandshakeException:握手失败
EDIT 2:
编辑2:
I am on Lollipop and using apache as my web server. My apache web server config has:
我在Lollipop上使用apache作为我的web服务器。我的apache web服务器配置有:
# SSL Protocol support:
# List the enable protocol levels with which clients will be able to
# connect. Disable SSLv2 access by default:
SSLProtocol all -SSLv2 -SSLv3
# SSL Cipher Suite:
# List the ciphers that the client is permitted to negotiate.
# See the mod_ssl documentation for a complete list.
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
Could this be my problem: HttpClient fails with Handshake Failed in Android 5.0 Lollipop
这可能是我的问题:在Android 5.0 Lollipop中,HttpClient失败与握手失败?
Not really sure what I need to change. I have looked all over and this seems to be the recommend config (for now).
我不太清楚我需要改变什么。我已经看过了,这似乎是推荐配置(现在)。
EDIT 3:
编辑3:
Here is the full stack trace:
这是完整的堆栈跟踪:
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ javax.net.ssl.SSLHandshakeException: Handshake failed
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:390)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.waitForHandshake(OpenSSLSocketImpl.java:623)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:585)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:75)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:88)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:175)
06-01 13:23:14.369 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:111)
06-01 13:23:14.371 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:134)
06-01 13:23:14.371 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:177)
06-01 13:23:14.371 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
06-01 13:23:14.371 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at mil.nga.giat.handshake.HandshakeActivity$SSLRequest.doInBackground(HandshakeActivity.java:115)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at mil.nga.giat.handshake.HandshakeActivity$SSLRequest.doInBackground(HandshakeActivity.java:85)
06-01 13:23:14.372 24486-24571/mil.nga.giat.handshake W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:292)
06-01 13:23:14.373 24486-24571/mil.nga.giat.handshake W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
06-01 13:23:14.373 24486-24571/mil.nga.giat.handshake W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
06-01 13:23:14.373 24486-24571/mil.nga.giat.handshake W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
06-01 13:23:14.373 24486-24571/mil.nga.giat.handshake W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
06-01 13:23:14.374 24486-24571/mil.nga.giat.handshake W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
06-01 13:23:14.374 24486-24571/mil.nga.giat.handshake W/System.err﹕ Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0xa21b8800: Failure in SSL library, usually a protocol error
06-01 13:23:14.374 24486-24571/mil.nga.giat.handshake W/System.err﹕ error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1303 0xb4b57be0:0x00000003)
06-01 13:23:14.375 24486-24571/mil.nga.giat.handshake W/System.err﹕ at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
06-01 13:23:14.375 24486-24571/mil.nga.giat.handshake W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:318)
2 个解决方案
#1
3
I never put the client cert in the KeyManager:
我从来没有把客户证书放在KeyManager中:
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keystore, "password".toCharArray());
sslContext.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);
#2
2
I am trying to get a mutual authentication request to work on android...
我正在努力获得一个关于android的相互认证请求…
(comment) Server CA is not installed on the device. It doesn't have to be. Only the client cert needs to be there to complete the handshake. That is why I am loaded a null truststore to allow the untrusted server cert.
(注释)服务器CA没有安装在设备上。不一定非得这样。只有客户端cert需要在那里完成握手。这就是为什么我要加载一个空信任库来允许不可信的服务器cert。
OK, so the easiest solution is to install the CA on the device. I understand you don't want to do that, and I don't really blame you. Its not the best solution because it tosses your CA into the mix with others in the CA Zoo.
最简单的解决办法是在设备上安装CA。我知道你不想这么做,我也不怪你。这并不是最好的解决办法,因为它会让你的CA与CA动物园的其他人混在一起。
Since you are doing this all programmatically, then I believe this is your solution: Use PEM Encoded CA Cert on filesystem directly for HTTPS request?. The client will validate the server certificate using your CA, and then continue with the client cert. The CA does not need to be installed on the device.
既然您都是通过编程的方式进行的,那么我相信这就是您的解决方案:直接使用PEM编码的CA Cert在文件系统上进行HTTPS请求?客户端将使用您的CA验证服务器证书,然后继续使用客户机cert。CA不需要安装在设备上。
Another alternative is a custom TrustManager
. But I prefer to let the system perform the checks rather than overriding behaviors and checks. There's a lot of checks you have to perform, and they are error prone. For starters, you have to know what RFCs to go to figure out what those checks are.
另一种选择是定制的TrustManager。但我宁愿让系统执行检查,而不是覆盖行为和检查。有很多检查必须执行,而且它们容易出错。首先,你必须知道rfc是什么,来弄清楚这些检查是什么。
I will use a custom TrustManager
for Public Key Pinning. There are lots of example of that; see, for example, Certificate and Public Key Pinning on OWASP's site. You can use pinning and forgo the checks because you don't need to confer trust. You either talk to the expected server - with public key X; or you don't - and it does not matter what a third party says (like a CA).
我将使用一个自定义的信任管理器来进行公钥固定。有很多这样的例子;例如,查看OWASP站点上的证书和公钥。你可以使用固定和放弃支票,因为你不需要给予信任。您可以与预期的服务器对话——使用公钥X;或者你不知道——第三方说什么(比如CA)并不重要。
Also be aware that Java and Android's SSLFactory
has some issues, like getInstance("TLS")
will also return SSLv3; and TLS 1.1 and 1.2 will be disabled. To fix that, see Which Cipher Suites to enable for SSL Socket?.
也要注意Java和Android的SSLFactory有一些问题,比如getInstance(“TLS”)也会返回SSLv3;TLS 1.1和1.2将被禁用。要修复这个问题,请查看为SSL套接字启用哪些密码套件?
Related to your edit:
有关你的编辑:
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256
EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL
!LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
This usually works fine:
这通常工作正常:
HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK
HIGH
will get you everything that's strong (about 112-bits of security and above).
HIGH会给你带来强大的东西(大约112比特的安全性和以上)。
!aNULL
removes anonymous protocols, and !kRSA
removes key transport (but not RSA signing) so you are left with Integer and Elliptic Curve Diffie-Hellman. You can see an example of RSA signing below with Au=RSA
.
aNULL删除了匿名协议,kRSA删除了密钥传输(但不是RSA签名),因此您只剩下了整数和椭圆曲线的Diffie-Hellman。您可以看到一个RSA与Au=RSA签名的例子。
HIGH
will also get you some weak/wounded cruft, like MD5
and RC4
, so you explicitly remove them. You also remove unneeded cipher suites, like SRP
and PSK
.
HIGH还会给你带来一些弱/受伤的cruft,比如MD5和RC4,所以你可以显式地删除它们。您还可以删除不需要的密码套件,如SRP和PSK。
You can check the ciphers under the string with openssl ciphers -v 'HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK'
:
你可以用openssl密码来检查字符串下面的密码:!aNULL:!
$ openssl ciphers -v 'HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK'
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
...
By the way, here is your string. All in all, I think it looks good. RC4 will give you the Obsolete Cryptography warnings from some browsers. Just ditch it since the padding oracles in block ciphers are fixed (again...).
顺便说一下,这是你的线。总而言之,我认为它看起来不错。RC4将提供一些浏览器中过时的加密警告。把它丢弃,因为阻塞密码的填充物是固定的(再一次…)。
$ openssl ciphers -v 'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384: \
EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS'
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-RC4-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=RC4(128) Mac=SHA1
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1
DHE-RSA-SEED-SHA SSLv3 Kx=DH Au=RSA Enc=SEED(128) Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1
ECDH-RSA-RC4-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128) Mac=SHA1
ECDH-ECDSA-RC4-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128) Mac=SHA1
RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1
#1
3
I never put the client cert in the KeyManager:
我从来没有把客户证书放在KeyManager中:
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keystore, "password".toCharArray());
sslContext.init(kmf.getKeyManagers(), new TrustManager[]{tm}, null);
#2
2
I am trying to get a mutual authentication request to work on android...
我正在努力获得一个关于android的相互认证请求…
(comment) Server CA is not installed on the device. It doesn't have to be. Only the client cert needs to be there to complete the handshake. That is why I am loaded a null truststore to allow the untrusted server cert.
(注释)服务器CA没有安装在设备上。不一定非得这样。只有客户端cert需要在那里完成握手。这就是为什么我要加载一个空信任库来允许不可信的服务器cert。
OK, so the easiest solution is to install the CA on the device. I understand you don't want to do that, and I don't really blame you. Its not the best solution because it tosses your CA into the mix with others in the CA Zoo.
最简单的解决办法是在设备上安装CA。我知道你不想这么做,我也不怪你。这并不是最好的解决办法,因为它会让你的CA与CA动物园的其他人混在一起。
Since you are doing this all programmatically, then I believe this is your solution: Use PEM Encoded CA Cert on filesystem directly for HTTPS request?. The client will validate the server certificate using your CA, and then continue with the client cert. The CA does not need to be installed on the device.
既然您都是通过编程的方式进行的,那么我相信这就是您的解决方案:直接使用PEM编码的CA Cert在文件系统上进行HTTPS请求?客户端将使用您的CA验证服务器证书,然后继续使用客户机cert。CA不需要安装在设备上。
Another alternative is a custom TrustManager
. But I prefer to let the system perform the checks rather than overriding behaviors and checks. There's a lot of checks you have to perform, and they are error prone. For starters, you have to know what RFCs to go to figure out what those checks are.
另一种选择是定制的TrustManager。但我宁愿让系统执行检查,而不是覆盖行为和检查。有很多检查必须执行,而且它们容易出错。首先,你必须知道rfc是什么,来弄清楚这些检查是什么。
I will use a custom TrustManager
for Public Key Pinning. There are lots of example of that; see, for example, Certificate and Public Key Pinning on OWASP's site. You can use pinning and forgo the checks because you don't need to confer trust. You either talk to the expected server - with public key X; or you don't - and it does not matter what a third party says (like a CA).
我将使用一个自定义的信任管理器来进行公钥固定。有很多这样的例子;例如,查看OWASP站点上的证书和公钥。你可以使用固定和放弃支票,因为你不需要给予信任。您可以与预期的服务器对话——使用公钥X;或者你不知道——第三方说什么(比如CA)并不重要。
Also be aware that Java and Android's SSLFactory
has some issues, like getInstance("TLS")
will also return SSLv3; and TLS 1.1 and 1.2 will be disabled. To fix that, see Which Cipher Suites to enable for SSL Socket?.
也要注意Java和Android的SSLFactory有一些问题,比如getInstance(“TLS”)也会返回SSLv3;TLS 1.1和1.2将被禁用。要修复这个问题,请查看为SSL套接字启用哪些密码套件?
Related to your edit:
有关你的编辑:
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256
EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL
!LOW !3DES !MD5 !EXP !PSK !SRP !DSS"
This usually works fine:
这通常工作正常:
HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK
HIGH
will get you everything that's strong (about 112-bits of security and above).
HIGH会给你带来强大的东西(大约112比特的安全性和以上)。
!aNULL
removes anonymous protocols, and !kRSA
removes key transport (but not RSA signing) so you are left with Integer and Elliptic Curve Diffie-Hellman. You can see an example of RSA signing below with Au=RSA
.
aNULL删除了匿名协议,kRSA删除了密钥传输(但不是RSA签名),因此您只剩下了整数和椭圆曲线的Diffie-Hellman。您可以看到一个RSA与Au=RSA签名的例子。
HIGH
will also get you some weak/wounded cruft, like MD5
and RC4
, so you explicitly remove them. You also remove unneeded cipher suites, like SRP
and PSK
.
HIGH还会给你带来一些弱/受伤的cruft,比如MD5和RC4,所以你可以显式地删除它们。您还可以删除不需要的密码套件,如SRP和PSK。
You can check the ciphers under the string with openssl ciphers -v 'HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK'
:
你可以用openssl密码来检查字符串下面的密码:!aNULL:!
$ openssl ciphers -v 'HIGH:!aNULL:!kRSA:!MD5:!RC4:!SRP:!PSK'
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
...
By the way, here is your string. All in all, I think it looks good. RC4 will give you the Obsolete Cryptography warnings from some browsers. Just ditch it since the padding oracles in block ciphers are fixed (again...).
顺便说一下,这是你的线。总而言之,我认为它看起来不错。RC4将提供一些浏览器中过时的加密警告。把它丢弃,因为阻塞密码的填充物是固定的(再一次…)。
$ openssl ciphers -v 'EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384: \
EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS'
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256
ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1
ECDHE-RSA-AES256-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1
ECDHE-ECDSA-AES256-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1
ECDHE-RSA-AES128-SHA SSLv3 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-AES128-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1
ECDHE-ECDSA-RC4-SHA SSLv3 Kx=ECDH Au=ECDSA Enc=RC4(128) Mac=SHA1
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(256) Mac=SHA256
DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(256) Mac=SHA1
DHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-SHA256 TLSv1.2 Kx=DH Au=RSA Enc=AES(128) Mac=SHA256
DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1
DHE-RSA-SEED-SHA SSLv3 Kx=DH Au=RSA Enc=SEED(128) Mac=SHA1
DHE-RSA-CAMELLIA128-SHA SSLv3 Kx=DH Au=RSA Enc=Camellia(128) Mac=SHA1
ECDH-RSA-RC4-SHA SSLv3 Kx=ECDH/RSA Au=ECDH Enc=RC4(128) Mac=SHA1
ECDH-ECDSA-RC4-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=RC4(128) Mac=SHA1
RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1