`
OpenMind
  • 浏览: 179547 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java-在非安全网络上建立可信任安全的通道(1/3)

 
阅读更多

      看到标题,几乎所有人都会想到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();
	}
}

 

 

分享到:
评论
1 楼 OpenMind 2012-10-05  
数据交互通道采用接口方式设计,是与通信协议无关的,实例使用的是socket,其实http连接的双方也可以通过不同的Pipe的实现做到交互密钥的。

相关推荐

    java网络编程源码

    5. **NIO(非阻塞I/O)**:Java NIO提供了选择器(Selector)、通道(Channel)和缓冲区(Buffer)等机制,可以提高网络编程的效率。源码中可能会有NIO相关的例子,如使用Selector监听多个Socket通道的事件。 6. **...

    javaSSL.zip

    Java SSL(Secure Socket Layer)和TLS(Transport Layer Security)是网络安全通信的重要组成部分,主要用于加密传输数据,确保网络上的敏感信息不被窃取或篡改。Java平台提供了对SSL/TLS协议的支持,使得开发者...

    基于SOCKET的数据传输安全技术研究——以JAVA SOCKET为例.zip

    本文将深入探讨基于Socket的数据传输安全技术,以Java Socket为例,阐述如何确保在网络中传输数据时的安全性。 一、Socket基础知识 Socket在计算机网络中扮演着客户端与服务器端通信的角色。它允许两台计算机通过...

    Java中的SSL及HTTPS协议实例源码.7z

    - 在安全通道上进行加密的数据传输。 在实际开发中,我们可能会遇到一些常见问题,例如证书不受信任、握手失败等。这时,我们需要根据具体情况调整`TrustManager`和`KeyManager`的配置,或者修改JVM的信任存储库。 ...

    SSL介绍与Java实例

    SSL(Secure Sockets Layer)是安全套接字层的缩写,它是一种广泛使用的网络通信安全协议,主要用于在客户端和服务器之间建立加密的、安全的数据传输通道。SSL能够确保在网络中传输的数据不被窃取或篡改,为互联网...

    Java安全通信

    SSL是一种用于在网络上传输数据的安全协议,最初由网景公司开发,后来演变为TLS(Transport Layer Security)。SSL位于TCP/IP协议之上,应用层协议之下,提供数据加密、身份验证和数据完整性保护功能。 ##### 2.1 ...

    Java中的SSL及HTTPS协议实例源码.rar

    Java中的SSL(Secure Socket Layer)和HTTPS(Hypertext Transfer Protocol Secure)协议是网络通信安全的重要组成部分,尤其在处理敏感信息如用户登录凭证、支付信息等时,它们扮演着至关重要的角色。SSL是一种用于...

    SSL及HTTPS协议_world_java_https客户端_ssl_distancemiy_

    SSL是一种用于网络通信的安全协议,它通过在客户端和服务器之间建立加密通道来保护数据的传输。SSL协议主要包括握手协议、记录协议、密钥交换协议和证书协议等组件。在握手过程中,客户端和服务器会协商加密算法、...

    java源码:Java中的SSL及HTTPS协议实例源码.rar

    握手完成后,我们就可以在安全的通道上进行数据传输了。 HTTPS协议是HTTP协议与SSL/TLS的结合,主要用于提供安全的网页浏览服务。当一个网站使用HTTPS时,浏览器会通过SSL/TLS与服务器建立加密连接,确保用户的登录...

    基于java NIO的http代理,支持https.zip

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它为Java应用程序提供了非阻塞I/O操作的能力,与传统的IO模型(基于流的IO)相比,NIO具有更高的性能和更好的可扩展性。在本项目中,“基于java NIO的http代理,...

    php mysql安全机制

    在部署MySQL时,减少其在网络上的可见度,例如放置在DMZ(非军事区)中,可以降低被恶意攻击的风险。 #### 11. 更新与补丁 及时安装MySQL的最新更新和安全补丁,修复已知的安全漏洞,是维护数据库安全的基础。 ##...

    Java Web之高级应用.ppt Java Web之高级应用.ppt

    4. **SSL/TLS的工作原理**:SSL/TLS协议在客户端和服务器之间建立安全通道。它们通过握手协议确定加密算法,交换证书,然后生成一个对称密钥用于数据传输。这个过程确保了数据的完整性和机密性,防止中间人攻击。 5...

    javamail收发邮件加密和不加密

    在使用JavaMail时,了解如何进行加密和非加密通信对于确保数据安全至关重要。 1. **POP3(Post Office Protocol version 3)**: - POP3是一种较老的协议,主要用于从邮件服务器下载邮件。在不加密的情况下,使用...

    python基于openssl的安全聊天系统源码.zip

    SSL(Secure Socket Layer)和TLS(Transport Layer Security)是互联网上广泛采用的加密和身份验证标准,它们为网络通信提供了一个安全通道。 该安全聊天系统的实现主要包括以下几个关键知识点: 1. **SSL/TLS...

    安全元件和基于白盒技术的综合防护在车联网中的应用

    在安全元件的防护能力方面,可以从非侵入式、半侵入式和侵入式三个层面进行评估。例如,可以通过侧信道攻击、干扰攻击、随机数验证等手段来测试安全元件的安全性能。此外,对于芯片可能受到的光、放射线等干扰,以及...

    https单项认证总结

    这些协议负责在客户端和服务器之间建立安全通道,包括身份验证、密钥交换和数据加密等步骤。 1. 握手过程:客户端发送一个“ClientHello”消息,包含支持的加密套件和随机数;服务器回应“ServerHello”,选择最佳...

    https 在weblogic应用

    HTTPS是HTTP的安全版本,它通过SSL或TLS(Transport Layer Security)协议在客户端和服务器之间建立安全通道。SSL/TLS协议主要负责以下几个关键任务: 1. **密钥交换**:客户端和服务器通过非对称加密算法(如RSA)...

    用于ssh文件同步,kotlin

    在IT行业中,SSH(Secure Shell)是一种广泛使用的网络协议,用于在不安全的网络上提供安全的远程登录和其他服务。Kotlin,作为一种现代、类型安全的编程语言,被越来越多的开发者用于构建各种应用程序,包括系统...

    cn1-transparent-test:对于 https

    1. **SSL/TLS协议**:HTTPS的基础是SSL/TLS协议,它负责在客户端和服务器之间建立安全通道,通过公钥/私钥加密技术和数字证书保证数据的保密性和完整性。 2. **Android中的HTTPS**: - **信任管理器**:在Android...

Global site tag (gtag.js) - Google Analytics