- 浏览: 177115 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (56)
- 算法 (9)
- linux (15)
- oracle (4)
- Project Euler Problem (3)
- 编程珠玑 (2)
- 数学 (1)
- http (1)
- java (19)
- plsql (1)
- apusic (1)
- https (1)
- 备忘 (22)
- 概率 (1)
- EIP (0)
- eclipse (1)
- 安全 (1)
- 公钥体系 (6)
- PKI (2)
- 网络 (2)
- linux,克隆 (0)
- virt-manager (1)
- VMWare (1)
- 克隆 (1)
- logback (1)
- TimeBasedRollingPolicy (0)
- SizeBasedTriggeringPolicy (0)
- properties (1)
- class (1)
- classloader (1)
- netty (1)
- thread dump (1)
- jstack (1)
- jconsole (1)
- java,编码,文件名 (0)
- google (1)
- goagent (1)
- 线程池 (1)
- 博客 (1)
- hexo (1)
- github (1)
- gitcafe (1)
最新评论
-
panhl:
我也实现了一个https://github.com/panho ...
具有相同属性任务串行有序执行的线程池设计 -
fengwei5129:
感谢,最近在看netty源码一直搞不清楚是如何实现的死锁检测, ...
Future机制用于并发编程时的死锁检测 -
OpenMind:
发现IBM JDK的System.nanoTime()没有实现 ...
Java系统时钟几个值得思考的问题 -
lvhongfen:
好了,感谢LZ分享
windows下plsql 设置 里面timestamp显示的格式 -
OpenMind:
今天发现,在linux下还有个很简介的方法查看线程的转储信息, ...
不依赖jstack的java 线程dump和死锁检查工具
看到标题,几乎所有人都会想到SSL,但SSL比较重量级,我想做的是只利用java的JCE体系(不是JSSE)在非安全网络环境下建立起一个可信任的、安全的通道。
所以这篇博文包括两个主题:可信任和安全。
这一节只考虑如何交互密钥。下一节(2/3)讨论如何建立信任关系,并在可信关系上交换密钥(防止中间人攻击)。
非对称密钥不适合做通道加密,通道加密必然使用对称密钥。既然如此,通信的双方(或多方)如何获取一个共同的密钥呢?
DH算法(Diffie-Hellman)是一种密钥协商算法,不理解原理的可以看这里:http://zh.wikipedia.org/wiki/Diffie-Hellman%E5%AF%86%E9%92%A5%E4%BA%A4%E6%8D%A2
下面的代码使用Java security api在socket通道上面演示密钥交换:
参考《Java security,2nd edition》
核心代码
public class DHKeyExchanger implements KeyExchanger { protected Pipe pipe; protected KeyPair dhKeyPair; protected PublicKey peerDHPublicKey; private byte[] key; /** * * @param pipe 密钥交互管道 */ public DHKeyExchanger(Pipe pipe) { this.pipe = pipe; } // 初始化DH密钥对 protected void init() throws SkipException { try { // Create a Diffie-Hellman key pair. KeyPairGenerator kpg = KeyPairGenerator.getInstance("DH"); kpg.initialize(SKIP.DHParameterSpec); dhKeyPair = kpg.genKeyPair(); } catch (InvalidAlgorithmParameterException e) { throw new SkipException("Invalid DH algorithm parameter.", e); } catch (NoSuchAlgorithmException e) { throw new SkipException("DH algorithm not supported.", e); } } // 发送dh公钥 protected void sendDHPublicKey() throws IOException, SkipException { byte[] keyBytes = dhKeyPair.getPublic().getEncoded(); write(keyBytes); } // 接收对方的dh公钥 protected void receiveDHPublicKey() throws IOException, SkipException { byte[] publicKeyBytes = read(); KeyFactory kf; try { kf = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509Spec = new X509EncodedKeySpec(publicKeyBytes); peerDHPublicKey = kf.generatePublic(x509Spec); } catch (NoSuchAlgorithmException e) { throw new SkipException("DH algorithm not supported.", e); } catch (InvalidKeySpecException e) { throw new SkipException("Invalid public key", e); } } // 生成密钥 public byte[] generateKey() throws SkipException { KeyAgreement ka; try { ka = KeyAgreement.getInstance("DH"); ka.init(dhKeyPair.getPrivate()); ka.doPhase(peerDHPublicKey, true); return ka.generateSecret(); } catch (NoSuchAlgorithmException e) { throw new SkipException("DH algorithm not supported.", e); } catch (InvalidKeyException e) { throw new SkipException("Invalid private key.", e); } } // all in one public void exchange() throws SkipException, IOException { this.init(); this.sendDHPublicKey(); this.receiveDHPublicKey(); this.key = generateKey(); } // read a byte array protected byte[] read() throws IOException { return pipe.read(); } // write a byte array protected void write(byte[] bytes) throws IOException { pipe.write(bytes); } @Override public byte[] getKey() { return key; } }
public interface KeyExchanger { public void exchange() throws SkipException, IOException; /** * @return 协商好的密钥 */ byte[] getKey(); }
public class SKIP { // SKIP's 1024 DH parameters private static final String SKIP1024String = "F488FD584E49DBCD20B49DE49107366B336C380D451D0F7C88B31C7C5B2D8EF6" + "F3C923C043F0A55B188D8EBB558CB85D38D334FD7C175743A31D186CDE33212C" + "B52AFF3CE1B1294018118D7C84A70A72D686C40319C807297ACA950CD9969FAB" + "D00A509B0246D3083D66A45D419F9C7CBD894B221926BAABA25EC355E92F78C7"; // Modulus private static final BigInteger SKIP1024Modulus = new BigInteger( SKIP1024String, 16); // Base private static final BigInteger SKIP1024Base = BigInteger.valueOf(2); public static final DHParameterSpec DHParameterSpec = new DHParameterSpec( SKIP1024Modulus, SKIP1024Base); }
数据交互通道:
public interface Pipe { byte[] read() throws IOException; void write(byte[] data) throws IOException; } public class DataPipe implements Pipe { DataInput in; DataOutput out; public DataPipe(InputStream in, OutputStream out) { super(); if (in instanceof DataInputStream) { this.in = (DataInputStream) in; } else { this.in = new DataInputStream(in); } if (out instanceof DataOutputStream) { this.out = (DataOutputStream) out; } else { this.out = new DataOutputStream(out); } } @Override public byte[] read() throws IOException { byte[] bytes = new byte[in.readInt()]; in.readFully(bytes); return bytes; } @Override public void write(byte[] data) throws IOException { out.writeInt(data.length); out.write(data); } }
测试代码:
public class Client { public static void main(String[] args) throws Exception { String host = "localhost"; int port =1111; // Open the network connection. byte[] key = exchangeFrom(host, port); System.out.println(Base64.encode(key)); } public static byte[] exchangeFrom(String host, int port) throws SkipException, IOException { Socket s = new Socket(host, port); Pipe pipe = new DataPipe(s.getInputStream(), s.getOutputStream()); KeyExchanger exchanger = new DHKeyExchanger(pipe); exchanger.exchange(); s.close(); return exchanger.getKey(); } } // public class Server { public static void main(String[] args) throws Exception { System.out.println(Base64.encode(exchangeFrom(1111))); } public static byte[] exchangeFrom(int port) throws SkipException, IOException { ServerSocket ss = new ServerSocket(port); // Wait for a connection. Socket s = ss.accept(); DataOutputStream out = new DataOutputStream(s.getOutputStream()); DataInputStream in = new DataInputStream(s.getInputStream()); Pipe pipe = new DataPipe(in, out); KeyExchanger exchanger = new DHKeyExchanger(pipe); exchanger.exchange(); s.close(); ss.close(); return exchanger.getKey(); } }
发表评论
-
具有相同属性任务串行有序执行的线程池设计
2014-09-04 15:30 1391我有一个这样的线程池的场景,相信很多人都遇到过: 1,每个用 ... -
不依赖jstack的java 线程dump和死锁检查工具
2013-10-08 14:41 2383java线程dump可以使用jdk的命令“jstack ... -
回忆去年用Java破解unity.exe的过程
2013-05-26 00:48 2585去年我一同学要我破解unity.exe,然后挂在网上卖点钱花 ... -
netty做Pipe一端快一端慢时防止内存溢出进行的操作
2013-05-23 17:12 5892前段时间用netty3.x做了 ... -
为什么InputStream.read()读取一个byte确返回一个int呢?
2013-05-09 16:26 5180问题1:为什么InputStream.read()读取一个 ... -
Java系统时钟几个值得思考的问题
2013-04-10 16:48 4558System.currentTimeMillis()是依赖 ... -
logback的SizeBasedTriggeringPolicy和TimeBasedRollingPolicy联合使用问题
2013-04-01 13:37 15176<appender name="FILE& ... -
netty应用分析
2013-03-07 15:54 0用netty 3.5.7做了一个网络程序,c与s之间有一个心 ... -
Java包装类Integer比较
2012-10-18 16:41 10771,用符号==比较两个对象,意味着比较他们是否是统一个对象。 ... -
Future机制用于并发编程时的死锁检测
2012-10-18 14:51 5949Netty源码里面有个类:De ... -
java-在非安全网络上建立可信任安全的通道(2/3)
2012-10-05 19:19 1212在不安全的网络环境下进行密钥交互(1/3,前面那一节),容易遭 ... -
java编程方式用CA给证书进行签名/签发证书
2012-10-05 18:02 11928这些代码首先加载CA证书,然后分别用CA给Alice和Bob签 ... -
java编程方式生成CA证书
2012-10-05 17:28 15278下面是java编程方式生成CA证书的代码,使用的是BC的pro ... -
安全领域的一些概念
2012-10-05 16:41 1382对称密钥/非对称密钥/key/cipher symmetri ... -
Class.getResourceAsStream
2013-04-06 14:09 977Class.getResourceAsStream(" ... -
findbugs
2012-03-02 16:41 0findbugsfindbugsfindbugsfindbug ... -
并发编程
2012-03-02 16:41 0C:\Users\Sunny\Desktop\docC:\Us ... -
泛型类里面获取到泛型的类型
2012-03-01 10:15 3411下面的代码可以让你在抽象的泛型类里面获取到泛型的类型 ab ... -
java 学习网站大全
2012-02-27 12:02 0http://scjp.home.sohu.com/ 模拟试题 ... -
车羊问题的一种简洁证明
2012-02-23 11:11 943在csdn上看到一篇关于车羊问题的文章(http://blog ...
相关推荐
selenium-java-2.47.1.zip,2015年8月更新
mysql-connector-java-5.1.27.jar mysql-connector-java-5.1.27.jar
mysql-connector-java-5.1.40-bin.jar连接器,用于在hive和mysql的数据库连接
5.6.20 最新JDBC mysql-connector-java-5.1.32-bin.jar
mysql驱动包 mysql-connector-java-5.1.13-bin.jar 方便快捷获取。。。
mysql-connector-java-5.1.42-bin.jar 官网下载的驱动
这是MySQL最新的jar,mysql-connector-java-8.0.18.jar
<artifactId>aliyun-java-sdk-core</artifactId> <version>3.2.2</version> </dependency> 如此引用即可,更多关于阿里云短信发送相关请参考http://blog.csdn.net/niaoer2010/article/details/78036664
mysql-connector-java-5.1.30-bin.jar 最新的mysql jdbc
mysql 的jdbc 驱动。mysql-connector-java-5.1.38-bin.jar
JAVA连MySQL驱动mysql-connector-java-5.1.25.jar
mysql-connector-java-8.0.11.jar连接器,用于在hive和mysql的数据库连接
使用C3P0额外依赖的一个jar包 :mchange-commons-java-0.2.3.4.jar
用于连接mysql数据库. mysql-connector-java-5.0.4-bin.jar
jdbc链接mysql数据库的jar包(mysql-connector-java-5.0.8-bin.jar)
MySQL官方提供的驱动包 mysql-connector-java-5.1.30.zip
jdbc的驱动jar包,有需要的童鞋自取。
java-1.7.0-openjdk devel rpm
mysql-connector-java-5.1.31-bin
java图片处理工具类JAR包 java-image-scalingjar