- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
在关于安全套接字的第10章Java Network Programming 4th Edition中,有一个构建安全服务器的示例。可以在here中找到该代码。
我正在尝试使代码更简单。这是我的代码:
try {
SSLContext context = SSLContext.getInstance(algorithm);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
//char[] password = System.console().readPassword("Password: "); // open the .class with command line
char[] password = {'t', 'h', 'i', 's', 'i', 's', 't', 'i', 'a', 'n'};
ks.load(new FileInputStream("src/jnp4e.keys"), password);
kmf.init(ks, password);
context.init(kmf.getKeyManagers(), null, null); // null = accept the default
// wipe the password
Arrays.fill(password, '0');
SSLServerSocketFactory factory
= context.getServerSocketFactory();
SSLServerSocket server
= (SSLServerSocket) factory.createServerSocket(PORT);
// add anonymous (non-authenticated) cipher suites
String[] supported = server.getSupportedCipherSuites();
String[] anonCipherSuitesSupported = new String[supported.length];
int numAnonCipherSuitesSupported = 0;
for (int i = 0; i < supported.length; i++) {
if (supported[i].indexOf("_anon_") > 0) {
anonCipherSuitesSupported[numAnonCipherSuitesSupported++]
= supported[i];
}
}
String[] oldEnabled = server.getEnabledCipherSuites();
String[] newEnabled = new String[oldEnabled.length
+ numAnonCipherSuitesSupported];
System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
System.arraycopy(anonCipherSuitesSupported, 0, newEnabled,
oldEnabled.length, numAnonCipherSuitesSupported);
server.setEnabledCipherSuites(newEnabled);
System.out.println("OK..");
// Now all the set up is complete and we can focus
// on the actual communication.
while (true) {
// This socket will be secure,
// but there's no indication of that in the code!
try (Socket theConnection = server.accept()) {
InputStream in = theConnection.getInputStream();
Reader r = new InputStreamReader(in, "UTF-8");
int c;
while ((c = r.read()) != -1) {
System.out.write(c);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
} catch (IOException | KeyManagementException | KeyStoreException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException ex) {
ex.printStackTrace();
}
Reader
,以便服务器可以读取字符。
int port = 7000; // default https port
String host = "localhost";
SSLSocketFactory factory
= (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = null;
try {
socket = (SSLSocket) factory.createSocket(host, port);
// enable all the suites
String[] supported = socket.getSupportedCipherSuites();
socket.setEnabledCipherSuites(supported);
Writer out = new OutputStreamWriter(socket.getOutputStream(), "UTF-8");
out.write("Hello");
}catch(Exception e){
}
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:189)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
...
flush()
和
close()
...
out.write("Hello");
out.flush();
socket.close();
...
javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
最佳答案
套接字流上的OutputStreamWriter显然正在缓冲,并且您的客户端没有.flush()
或.close()
,因此实际上并未发送您的数据。
如果您的Java程序(或更确切地说是JVM)在没有对套接字流执行.close()
的情况下退出(包括关闭传递给Stream的Writer),则处理取决于平台;在Windows上,它会发送RST,从而导致您在对等端看到“连接重置”异常。 Unix通常在TCP级别上关闭连接,这实际上对于SSL / TLS而言并不完全正常,但是“足够接近”(实际上)使得Java将其视为EOF。
编辑后续问题:
服务器收到SSLHandshakeException“接收到警报bad_certificatecertificate_unknown”,从理论上讲可能有几件事,但几乎总是意味着该服务器正在使用的证书(来自您加载的密钥库以及匹配的私钥)未由受信任的CA(证书颁发机构)签名客户端。
您为客户端显示的代码不执行任何操作来设置或更改其信任库;如果没有其他代码可以执行此操作,或者没有外部设置(例如java
命令行选项-Dx=y
来设置系统属性),则客户端将使用JSSE默认信任库,如果文件JRE/lib/security/jssecacerts
存在,则为文件JRE/lib/security/cacerts
,否则,文件jssecacerts
(其中JRE是JRE的安装目录;如果使用JDK,则JRE是JDK目录的子目录)。如果自安装JRE以来您(和系统上的其他任何人)都没有修改这些文件,则cacerts
不存在,并且keytool -genkeypair
包含由Oracle确定的一组“知名根” CA,例如Verisign和Equifax等
因此,您需要:
使用由知名CA颁发的证书;如果您还没有这样的证书,则必须通过证明(至少)控制您所认证的域名并取决于CA来支付费用,才能从CA获得该证书;如果您确实拥有或获得了这样的证书,则将其与任何链证书一起安装在您的密钥库中的私钥条目中(对于著名的CA,几乎总是有至少一个链证书)。
使用由任何其他CA颁发的证书,包括您组成的临时CA,并在限制条件下使用自签名证书,该证书本身就是它自己的CA,例如自动生成的jssecacerts
;并将该CA的CA证书(或该自签名证书)放入客户端使用的信任库中。为此,有两种方法:
将服务器的CA证书(或自签名证书)放入客户端使用的JRE的默认信任库文件中。这确实会影响共享该默认信任库的任何其他程序,这可能是所有使用该JRE的其他程序。如果使用cacerts
,则仅影响JSSE;如果使用keytool -genkeypair -keystore ksfile -keyalg RSA
,则还影响对签名代码(如果有)的验证,并且,如果在适当的位置升级JRE,它也将消失,这在Windows上通常是自动的。
创建(或重用)另一个信任库,将服务器的CA证书放入其中,然后让客户端使用该非默认信任库。有几个选项:在外部设置默认信任库的系统属性,在程序中显式设置它们(在首次使用JSSE之前!),显式加载“密钥库”文件(实际上包含证书)并使用它在非默认SSLSocketFactory中的trustmanager,就像您的服务器代码对keymanager所做的一样,甚至使用您喜欢的任何商店编写自己的trustmanager并类似地使用。
编辑#2简单示例
详细介绍所有这些选项可能太长了,但是一个简单的选项如下。
生成密钥对和(默认)自签名证书:-dname "CN=common_name_value"
对于提示“名字和姓氏”(实际上是证书中的CommonName属性),请输入服务器的名称,特别是客户端将用于连接服务器的名称;在问题中,这是“本地主机”。其他名称字段无关紧要;根据您的喜好填写或忽略它们,但提示时显示的国家(如果使用)必须为2个字母。无需回答提示,您可以在命令行-alias name
上添加。如果服务器的名称不只一个,此处将省略一些选项。
对于其他一些应用程序,您可能需要使用keytool -exportcert -rfc -keystore ksfile [-alias name] -file certfile
指定条目名称。对于此问题,则不需要。
获取证书的副本:keytool -importcert -keystore JRE/lib/security/cacerts -file certfile
在此示例中,客户端与服务器位于同一台计算机上。在另一种情况下,有必要将该文件的内容从服务器复制到客户端。通常,通过复制文件可以最方便地完成此操作。
将证书放入客户端信任库。如上所述,有很多选项,但是您可能会经常看到一个建议,因为通常启动最快的方法是将其放在JRE默认文件cacerts中:java
其中,JRE是您的JRE(Java运行时环境)的安装目录。这取决于您的操作系统以及如何与软件包管理器一起安装JRE(或JDK,包括JRE)。如果您安装了多个JRE和/或JDK,则取决于您使用的是哪个。
在Unix上,如果您在未指定路径的情况下调用which java
,则type java
(或者在bash和其他shell中,可能是/somewhere/java[version]/bin/java
)将告诉您所运行的完整路径名。但是请注意,这通常是指向实际位置的符号链接,其格式应为bin/java
;将lib/security/cacerts
部分更改为%windir%\system32\java.exe
。
在Windows上,如果安装普通的“系统范围” Java,则运行的程序为windir
,其中c:\windows
通常为c:\program files\java\jreN
,但是JRE的实际代码和文件位于c:\program files (x86)\java\jreN
或jre7
中,具体取决于在您的体系结构(32位或64位)上,并且jreN当前为jre8
或
关于java - Java-SocketException:客户端发送请求时重置连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31064883/
我正在使用 Json 数据创建 ListView 。我正在填充一些图像、文本字段和一个按钮。当用户单击按钮时,按钮标题会发生变化。 问题是如果按钮被修改并且用户滚动 ListView 按钮重置为第一个
在我的 iOS 测验应用程序中,您有 15 秒的时间来回答问题。如果回答正确,则会出现第二个 View Controller ,然后单击第二个 View Controller 上的按钮将其关闭,并且第
我现在使用 Objective-C 在 iOS 中实现一个功能,即当 slider 值发生变化时,在 slider 的“节点”上方制作一个文本标签。文本标签文本是 slider 的当前值。 因此,我在
所以我有一个名为 AuthStack 的堆栈像这样 const AuthStack = ({ resetPassword, updateEmail }: any) => (
在我的 Flutter 小部件中,我有一个 StreamBuilder检查 snapshot.hasError在这种特定情况下,它将返回我的 ErrorRetryWidget() . builder:
如果我的手机 hibernate 或我离开应用程序发送短信/接听电话,我的应用程序将重新启动。我该如何防止这种情况? 我希望保存对象而不是基本数据类型。如果应用程序关闭或手机关闭,我不需要保存应用程序
我有一个如下所示的数据框: ID TIME AMT 1 0 50 1 1 0 1 2 0 1 3 0 1 4 0 1 4 5
我正在使用 org.eclipse.swt.widgets.Combo 类,我正在执行以下操作 Combo myCombo = new Combo(container, SWT.READ_ONLY);
我有一个 UISWitch 默认位置设置为 off 用户可选择将开关设置为on,我如何通过另一个按钮/操作将该开关重新关闭。 - (IBAction)switchToggled:(id)sender
我试图让玩家 Sprite 节点在接触到危险节点时重置。我怎样才能做到这一点?该代码不起作用。 if player.position == danger.position { player.p
我尝试在启动 UITests 时重置和恢复 UserDefaults 并在它们分别完成时恢复它们。这是在 AppDelegate 中使用的代码: func makeDefaultsBackup() {
我有一个公用事业账单分段表,其中每个分段表示一个月的千瓦时使用情况。我想将 12 人一组合计起来以获得年度账单。 变量bill_cd表示年度账单的最后一部分。 Data download cu
我刚刚使用 composer 为项目安装了一些依赖项。在这个项目中,我们使用 cartalyst/sentry-social 包。为此,我必须使用一个特殊的 GitHub 帐户——但我不知道我在使用该
我对 Marionette collectionView 有疑问。当我没有定义 el 时 var featureditems = new View.CarouselItems({ collection
我有一个knockout/mvc3应用程序。我正在将日期传递回 Controller 。 Controller public ActionResult PackageUpdate(Package up
我有 2 个 Activity ,在第二个 Activity 中,我阅读并对本地 JSON 文件进行了一些更改,它适用于我需要的所有内容,但是当我转到 mainActivity 然后返回到第二个 Ac
我有一个带有 .xib 的 UIViewController,它有 2 个名为“LblA”和“LblB”的 UILable。让我们将此 ViewController 称为“A”。 LblA 和 Lbl
该模型将 LSTM 作为其第一层。 在调用 model.predict 时说你传入了几个样本: >sam = np.array([ [[.5, .6, .3]], [[.6, .6, .3]], [[
我开始使用 Angular.JS。 我有许多共享同一个 Controller 的 View 。每个 View 都是收集存储在 Controller 中的数据的一个步骤: $routeProvider.
我已经使用 DDEV 几天了,它很棒。 但是我发现如果我运行 ddev ssh通过 ssh 进入容器,并通过 npm / aptitude 安装包等等,或者如果我在 ~/ 中创建新文件主目录,有时这些
我是一名优秀的程序员,十分优秀!