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

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

阅读更多

       这篇博文的前两节(1/3,2/3)已经介绍了如何在不安全网络环境下面相互认证双方的身份(建立信任的连接),以及在此基础上进行可靠的密钥协商(DH算法)。

       这一节将介绍如何使用协商好的密钥对通道上流淌的数据进行加密。我将使用AES作为对称密钥的算法,密钥强度:128位。这个过程可以简单概括成下面两个步骤:

 

  • 利用协商好的key创建一个可以用于加密和解密的Aes Cipher;
  • 使用这个cipher对一个byte数组进行加密和解密。
直接上代码吧:
/**
 * 使用AES 128bit 算法进行加密和解密的工具类
 * 
 * @author atlas
 * @date 2012-9-18
 */
public class AESCipher {
	private static final int bsize = 16;
	private static final int ivsize = 16;
	private Cipher dCipher;
	private Cipher eCipher;

	private AESCipher(Cipher dCipher, Cipher eCipher) {
		this.eCipher = eCipher;
		this.dCipher = dCipher;
	}

	public static AESCipher getInstance(byte[] key) throws CryptoException {
		String pad = "PKCS5Padding";
		try {
			byte[] tmpKey = ChecksumUtil.getChecksumAsBytes("md5", key);
			byte[] tmpIV = new byte[ivsize];
			if (key.length <= ivsize) {
				System.arraycopy(key, 0, tmpKey, 0, key.length);
			} else if (key.length > ivsize) {
				System.arraycopy(key, 0, tmpIV, 0, tmpIV.length);
			}
			SecretKeySpec keyspec = new SecretKeySpec(tmpKey, "AES");
			IvParameterSpec ivSpec = new IvParameterSpec(tmpIV);
			Cipher dcipher = Cipher.getInstance("AES/CBC/" + pad);
			Cipher ecipher = Cipher.getInstance("AES/CBC/" + pad);
			ecipher.init(Cipher.ENCRYPT_MODE, keyspec, ivSpec);
			dcipher.init(Cipher.DECRYPT_MODE, keyspec, ivSpec);
			return new AESCipher(dcipher, ecipher);
		} catch (Exception e) {
			throw new CryptoException("initializing AESCipher fail.", e);
		}
	}

	/**
	 * 
	 * @param str
	 * @return
	 * @throws CryptoException
	 */
	public String encrypt(String str) throws CryptoException {
		try {
			// Encode the string into bytes using utf-8
			byte[] utf8 = str.getBytes("UTF8");
			// Encrypt
			byte[] enc = this.eCipher.doFinal(utf8);
			// Encode bytes to hex string
			return StringUtils.bytesToHex(enc);
		} catch (Exception e) {
			throw new CryptoException("encrypt failed.", e);
		}
	}

	public String decrypt(String str) throws CryptoException {
		try {
			byte[] dec = StringUtils.hexToBytes(str);
			// Decrypt
			byte[] utf8 = this.dCipher.doFinal(dec);
			// Decode using utf-8
			return new String(utf8, "UTF8");
		} catch (Exception e) {
			throw new CryptoException("decrypt failed.", e);
		}
	}

	public byte[] encrypt(byte[] message) throws CryptoException {
		try {
			// Encrypt
			return this.eCipher.doFinal(message);
		} catch (Exception e) {
			throw new CryptoException("encrypt failed.", e);
		}
	}

	/**
	 * 这个方法是为了尽可能少的减少内存拷贝,input buffer和output
	 * buffer可以是一个byte数组,不过调用者需要保证output可以输出数据的长度要足够大,即能够容纳加密后的padding。
	 * 这个padding不会超过 {@link #getBsize() }-1
	 * 
	 * @param input
	 *            待加密的buffer
	 * @param inputOffset
	 *            待加密的数据在input buffer中的起始位置(从0开始)
	 * @param inputLen
	 *            待加密的数据的长度,不超过(input.length-inputOffset).
	 * @param output
	 *            加密后的数据的输出buffer。
	 * @param outputOffset
	 *            输出buffer的起始位置。
	 * @return 在output里面实际解密的数据长度
	 * 
	 * @throws ShortBufferException
	 *             如果output buffer太小,无法容纳输出结果
	 */
	public int encrypt(byte[] input, int inputOffset, int inputLen,
			byte[] output, int outputOffset) throws CryptoException {
		try {
			return eCipher.doFinal(input, inputOffset, inputLen, output,
					outputOffset);
		} catch (Exception e) {
			throw new CryptoException("encryption failed", e);
		}
	}

	/**
	 * 这个方法是为了尽可能少的减少内存拷贝,input buffer和output buffer可以是同一个byte数组。
	 * 
	 * @param input
	 *            待解密的buffer
	 * @param inputOffset
	 *            待解密的数据在input buffer中的起始位置(从0开始)
	 * @param inputLen
	 *            待解密的数据的长度,不超过(input.length-inputOffset).
	 * @param output
	 *            解密后的数据的输出buffer。
	 * @param outputOffset
	 *            输出buffer的起始位置。
	 * @return 在output里面实际解密的数据长度
	 * @throws ShortBufferException
	 *             如果output buffer太小,无法容纳输出结果
	 */
	public int decrypt(byte[] input, int inputOffset, int inputLen,
			byte[] output, int outputOffset) throws CryptoException {
		try {
			return dCipher.doFinal(input, inputOffset, inputLen, output,
					outputOffset);
		} catch (Exception e) {
			throw new CryptoException("decryption failed", e);
		}
	}

	/**
	 * 返回需要的padding的长度
	 * 
	 * @param len
	 * @return
	 */
	public int pad(int len) {
		return eCipher.getOutputSize(len) - len;
	}

	public byte[] decrypt(byte[] message) throws CryptoException {
		try {
			// Decrypted
			byte[] decrypted = this.dCipher.doFinal(message);
			return decrypted;
		} catch (Exception e) {
			throw new CryptoException("decrypt failed.", e);
		}
	}
}
 
 几个工具类的代码我就不贴了。

 

 

分享到:
评论

相关推荐

    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协议的支持,使得开发者...

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

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

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

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

    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是一种用于...

    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代理,...

    SSL及HTTPS协议_world_java_https客户端_ssl_distancemiy_

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

    javamail收发邮件加密和不加密

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

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

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

    php mysql安全机制

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

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

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

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

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

    https单项认证总结

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

    用于ssh文件同步,kotlin

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

    https 在weblogic应用

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

    IIS6.0 IIS,互联网信息服务

    除了匿名访问用户(Anonymous)外,IIS中的FTP将使用Windows 2000自带的用户库(可在“开始→程序→管理工具→计算机管理”中找到“用户”一项来进行用户库的管理)。 最后,关键一步还有就是将你的电脑变为网络中的...

Global site tag (gtag.js) - Google Analytics