前端时间公司有需求要访问客户端串口读取电子称的数据,通过网上资料,决定使用applet通过电子签名的形式实现。

1.先写applet:这里我是使用RXRTcomm.jar

LocalFileApplet.java,JobThread.java

public class LocalFileApplet extends Applet {
private static final String LIB_PATH_SUFFIX = "system32";
private static final String DLL_FILE = "rxtxSerial.dll";
private String msg = "";
private boolean ready;
private boolean right=true;
private String commName;
CommPortIdentifier portId ;
SerialPort serialPort;
InputStream is;
public boolean isRight() {
return right;
}
public void setRight(boolean right) {
this.right = right;
}
public CommPortIdentifier getPortId() {
return portId;
}
public void setPortId(CommPortIdentifier portId) {
this.portId = portId;
}
public SerialPort getSerialPort() {
return serialPort;
}
public void setSerialPort(SerialPort serialPort) {
this.serialPort = serialPort;
}
public InputStream getIs() {
return is;
}
public void setIs(InputStream is) {
this.is = is;
}
public boolean isReady() {
return ready;
}
public void setReady(boolean ready) {
this.ready = ready;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCommName() {
return commName;
}
public void setCommName(String commName) {
this.commName = commName;
}
static{
//System.setSecurityManager(null);
System.setSecurityManager(null);
String drivername = "gnu.io.RXTXCommDriver";
try {
CommDriver driver = (CommDriver) Class.forName(drivername).newInstance();
driver.initialize();
} catch (InstantiationException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalAccessException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (ClassNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
} public void paint(Graphics g ){
//showPorts(g);
}
public void initPort() throws NoSuchPortException {
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(commName);
if (!portId.isCurrentlyOwned()) {
SerialPort port;
try {
port = (SerialPort) portId
.open("SerialMain", );
port.setSerialPortParams(, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
is = port.getInputStream();
System.out.println("得到inputstream");
} catch (PortInUseException e) {
// TODO Auto-generated catch block
cleanPort();
e.printStackTrace();
} catch (UnsupportedCommOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
} public void cleanPort(){
try {
is.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
serialPort.close();
}
public void init(){
//listPorts();
System.out.println("");
x();
this.setBounds(,,,);
this.repaint();
} public void start(){
try {
initPort();
} catch (NoSuchPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.setRight(false);
}
JobThread job = new JobThread(this);
Thread t = new Thread(job);
t.start();
}
public void stop(){
cleanPort();
}
private void showPorts(Graphics g ){
g.drawString("扫描本地计算机上的串口:!",,);
String[] ports = listPorts().split(",");
if(ports.length==){
g.drawString("本地计算机上没有发现串口:!",,);
}else{
int y = ;
g.drawString("本地计算机上发现"+ports.length+"个串口:!",,);
for (int i = ; i < ports.length; i++) {
String port = (String) ports[i];
g.drawString(port,,y);
y += ;
}
}
}
public String listPorts(){
String commName="";
Enumeration en = CommPortIdentifier.getPortIdentifiers();
CommPortIdentifier portId;
while (en.hasMoreElements()) {
portId = (CommPortIdentifier) en.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL){
if(commName==""){
commName+=portId.getName();
}else{
commName+=","+portId.getName();
}
}
}
return commName;
}
private void downDll(){ try {
// 获取加载库时搜索的路径列表
String dirs = System.getProperty("java.library.path");
String[] libs = dirs.split(";");
String libPath = "";
for (String lib : libs) {
if (lib.toLowerCase().endsWith(LIB_PATH_SUFFIX)) {
libPath = lib;
break;
}
}
File dll = new File(libPath, DLL_FILE);
if (!dll.exists()) {
URL url = new URL(super.getCodeBase() + DLL_FILE);
InputStream is = url.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(dll);
byte[] buf = new byte[]; // 读取缓存
int len = ;
while ((len = is.read(buf)) != -) {
fos.write(buf, , len);
}
fos.flush();
fos.close();
is.close();
System.out.println("创建文件完成[" + dll + "].");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
public void x() {
try {
// 获取加载库时搜索的路径列表
String dirs = System.getProperty("java.library.path");
String[] libs = dirs.split(";");
String libPath = "";
for (String lib : libs) {
if (lib.toLowerCase().endsWith(LIB_PATH_SUFFIX)) {
libPath = lib;
break;
}
}
File dll = new File(libPath, DLL_FILE);
if (!dll.exists()) {
URL url = new URL(super.getCodeBase() + DLL_FILE);
InputStream is = url.openConnection().getInputStream();
FileOutputStream fos = new FileOutputStream(dll);
byte[] buf = new byte[]; // 读取缓存
int len = ;
while ((len = is.read(buf)) != -) {
fos.write(buf, , len);
}
fos.flush();
fos.close();
is.close();
System.out.println("创建文件完成[" + dll + "].");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally{
System.loadLibrary("rxtxSerial");
}
}
}
public class JobThread implements Runnable{
private LocalFileApplet applet;
public JobThread(LocalFileApplet applet) {
this.applet = applet;
}
public void run() {
InputStream is = applet.getIs();
try {
while(true){
String msg="";
byte[] str = new byte[];
System.out.println("准备接收数据");
is.read(str);
System.out.println("收到数据" + new String(str)); String txt[] = new String[];
String value = new String(str);
if (value != null) {
String vxxx[] = value.split(",");
if (vxxx.length > ) {
String[] a = value.split(",")[].split(" "); int i = ;
for (String v : a) {
if (v.length() > ) {
txt[i] = v;
i++;
}
}
if (txt[].length() == ) {
msg = txt[].substring(,
txt[].length() - )
+ "."
+ txt[].substring(txt[].length() - ,
txt[].length());
} else {
msg = txt[].substring(,
txt[].length() - )
+ "."
+ txt[].substring(txt[].length() - ,
txt[].length());
}
}
if(msg==""||applet.getMsg().equals(msg)){
applet.setMsg(msg);
applet.setReady(false);
System.out.println(msg);
applet.repaint();
}else{
applet.setMsg(msg);
applet.setReady(true);
System.out.println(msg);
applet.repaint();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

然后用eclipse打包,到这里都很顺利,然后签名的时候遇到了很多问题。

正确的方法是:

服务器端:

1.为刚才创建的包文件(LocalFileApplet.jar)创建keystore和keys。

keytool -genkey -keystore LocalFileApplet.keystore –alias LocalFileApplet -keyalg DSA

2.用LocalFileApplet.keystore 对签名LocalFileApplet.jar

jarsigner -keystore LocalFileApplet.keystore LocalFileApplet.jar LocalFileApplet

3.生产LocalFileApplet.cer(这个是客户端需要的秘钥)

keytool -export -keystore LocalFileApplet.keystore -alias LocalFileApplet-file LocalFileApplet.cer

客户端:

1.找到jre(1.7以上版本,1.6没有例外站点)把LocalFileApplet.cer导入到cacerts

路径:***\jre1.8.0_45\lib\security

keytool -import -alias LocalFileApplet -file LocalFileApplet.cer -keystore cacerts

2.修改策略文件java.plicy

添加keystore "file:/C:/Program Files (x86)/Java/jre1.8.0_45/lib/security/cacerts", "JKS";

在grant下面增加

permission java.lang.RuntimePermission "loadLibrary.rxtxSerial", "read";
permission java.util.PropertyPermission "java.library.path", "read";
permission java.util.PropertyPermission "java.library.path", "write";
permission java.io.FilePermission "C:/Windows/system32/rxtxSerial.dll", "read";
permission java.io.FilePermission "C:/Windows/system32/rxtxSerial.dll", "write";
permission java.io.FilePermission "C:/Program Files (x86)/Java/jre1.8.0_45/lib/ext/amd64/rxtxSerial.dll", "read";
permission java.io.FilePermission "C:/Program Files (x86)/Java/jre1.8.0_45/lib/ext/amd64/rxtxSerial.dll", "write";
permission java.util.PropertyPermission "gnu.io.rxtx.SerialPorts","read";
permission java.lang.RuntimePermission "setSecurityManager";

3.把rxtxSerial.dll放到C:\Windows\System32下

4.配置本地java,打开:控制面板\程序\java 安全 例外站点
把服务器网站输入例如:http://localhost:8080/demo/

注:以/结尾,否则无效

5.高级:JNLP 文件/MIME 关联 选为始终允许,
安全执行环境勾选 允许用户为签名的内容授予权限 允许用户解释JNLP安全请求
混合代码 (沙箱代码与可信代码) 安全验证 选 启动-隐藏警告并在保护下运行
对以下项执行已签名代码证书撤销检查 选 不检查
对以下项执行 TLS 证书撤销检查 选 不检查

然后在html中调用applet

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<script type="text/javascript">
var t;
function startComm(){
document.applets["myapp"].start();
process();
}
function process(){
var ready = document.applets["myapp"].isready();
if(ready){
// document.applets["myapp"].setReady(false);
var msg = document.applets["myapp"].getMsg();
document.getElementById("t").value=msg;
}
t=setTimeout('process()',);
}
function showComm(){
var commName = document.applets["myapp"].listPorts();
var html=""; //<option value ="">Volvo</option>
var names=commName.split(",");
for(var i=;i<names.length;i++){
html+=" <option value ='"+names[i]+"'>"+names[i]+"</option>"
}
document.getElementById("commNum").innerHTML=html; document.applets["myapp"].setCommName(names[]);
}
function changeComm(){
var commName =document.getElementById("commNum").value();
document.applets["myapp"].setCommName(commName);
}
function closeComm(){
clearTimeout(t);
}
</script>
<body onload="showComm()">
<!--"CONVERTED_APPLET"-->
<!-- HTML CONVERTER -->
<APPLET CODEBASE="." CODE="com.LocalFileApplet.class" ARCHIVE="LocalFileApplet.jar,RXTXcomm.jar" WIDTH="" HEIGHT="" name="myapp"> </APPLET>
<!--"END_CONVERTED_APPLET"-->
<input type="button" value="确定" id="x" onclick="startComm()">
<input type="button" value="关闭" id="s" onclick="closeComm()">
<input id="t" type="text" value="" >
<select id="commNum" onkeyup="showComm()" onchange="changeComm()">
</select>
</body>
</html>

很奇怪,这样写不能读,最后我无奈了,就不打包,直接引用com.LocalFileApplet.class,可以了

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<script type="text/javascript">
var t;
function startComm(){
document.applets["myapp"].start();
process();
}
function process(){
var ready = document.applets["myapp"].isready();
if(ready){
// document.applets["myapp"].setReady(false);
var msg = document.applets["myapp"].getMsg();
document.getElementById("t").value=msg;
}
t=setTimeout('process()',);
}
function showComm(){
var commName = document.applets["myapp"].listPorts();
var html=""; //<option value ="">Volvo</option>
var names=commName.split(",");
for(var i=;i<names.length;i++){
html+=" <option value ='"+names[i]+"'>"+names[i]+"</option>"
}
document.getElementById("commNum").innerHTML=html; document.applets["myapp"].setCommName(names[]);
}
function changeComm(){
var commName =document.getElementById("commNum").value();
document.applets["myapp"].setCommName(commName);
}
function closeComm(){
clearTimeout(t);
}
</script>
<body onload="showComm()">
<!--"CONVERTED_APPLET"-->
<!-- HTML CONVERTER -->
<APPLET CODEBASE="." CODE="com.LocalFileApplet.class" ARCHIVE="RXTXcomm.jar" WIDTH="" HEIGHT="" name="myapp">
</APPLET>
<!--"END_CONVERTED_APPLET"-->
<input type="button" value="确定" id="x" onclick="startComm()">
<input type="button" value="关闭" id="s" onclick="closeComm()">
<input id="t" type="text" value="" >
<select id="commNum" onkeyup="showComm()" onchange="changeComm()">
</select>
</body>
</html>

难道是LocalFileApplet.jar签名出问题了?

但是RXTXcomm.jar同样签名的,为什么RXTXcomm.jar签名有效,LocalFileApplet.jar签名无效

使用java applet通过签名访问客户端串口的更多相关文章

  1. Java Applet读写client串口——终极篇

    測试环境: SDK:Oracle JRockit for Java version 6, Java Communication for Windows 2.0 OS:WINDOWS7 外设:串口条形码 ...

  2. 使用Java Applet在客户端解压缩,以及使用证书的意义

    以前解压缩是用Java Applet在客户端解压缩,而且用户不知道这回事.但是现在Chrome不支持NP API了,所以不得不把Java去掉,然后在服务器里解压缩.风险在于,解压缩以后,传输到客户端的 ...

  3. Java—Applet

    1  Applet的定义 Applet是Java语言编写的,无法独立运行,但可以嵌入到网页中执行.它扩展了传统的编程结构和方法,可以通过互联网发布到任何具有Java编译环境浏览器的个体计算机上. 如下 ...

  4. Java Applet小应用

    开发和部署方式     嵌入到HTML网页中,用<Applet></Applet>标签识别.java环境用浏览器的,在第一次打开时下载,可开发成以后打开,默认不必再次下载.也可 ...

  5. 解决HMC在IE浏览器无法登录的问题(Java Applet的使用问题)

    管理IBM的小型机必须要用到HMC(Hardware Management Console),有时候在使用测试环境使用的时候我们会把HMC装到自己电脑上的虚拟机里面,然后管理小型机,但是在虚拟机里面使 ...

  6. Java实现UDP之Echo客户端和服务端

    Java实现UDP之Echo客户端和服务端 代码内容 采用UDP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...

  7. Java实现TCP之Echo客户端和服务端

    Java实现TCP之Echo客户端和服务端 代码内容 采用TCP协议编写服务器端代码(端口任意) 编写客户机的代码访问该端口 客户机按行输入 服务器将收到的字符流和接收到的时间输出在服务器consol ...

  8. Java Applet与Java Application的特点

    java application是应用程序,用于桌面开发,java applet是小应用程序,一般嵌入到网页里运行.applet一般用于B/S页面上作为插件式的开发,而application主要是桌面 ...

  9. API访问客户端

    API访问客户端(WebApiClient适用于MVC/WebForms/WinForm) 这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前 ...

随机推荐

  1. Web渗透测试(xss漏洞)

    Xss介绍—— XSS (cross-site script) 跨站脚本自1996年诞生以来,一直被OWASP(open web application security project) 评为十大安 ...

  2. Windowns DOS For 循环实例

    update_all.bat代码示例: @echo off echo ***************************************************************** ...

  3. django 实现电子支付功能

    思路:调用第三方支付 API 接口实现支付功能.本来想用支付宝来实现第三方网站的支付功能的,但是在实际操作中发现支付宝没有 Python 接口,网上虽然有他人二次封装的的 Python 接口,但是对我 ...

  4. linux+python+robot+jenkins

    1.安装python 安装devtoolset # yum groupinstall “Development tools” 安装编译Python需要的包 # yum -y install zlib- ...

  5. Python数组(二)

    一.函数list 可将任何序列(如字符串)作为list的参数.list实际上是一个类,而不是函数. test=['java','C#','C','C++'] print(list(test)) ——& ...

  6. 【离散数学】 SDUT OJ 传递闭包 && memset 使用注意事项

    传递闭包 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 已知有n头牛,m次战斗关系, ...

  7. 搭建vue环境网站

    https://cli.vuejs.org/zh/guide/installation.html 安装成功vue脚手架 安装成功3.4版本 vue + iview项目构建 https://blog.c ...

  8. docker记录

    # docker run 运行程序 # docker stop (docker kill) 终止容器. (首先应该执行 docker stop!!) #停止所有容器 docker stop $(doc ...

  9. mock static方法

    <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mock ...

  10. hadoop 配置安装

    1.   下载hadoop 压缩包,   拷贝到 /usr/hadoop目录下   tar -zxvf  hadoop-2.7.1.tar.gz, 比如: 127.0.0.1 localhost 19 ...