java-在非安全网络上建立可信任安全的通道(3/3)
来源:互联网 发布:mac os系统如果支持win 编辑:程序博客网 时间:2024/06/04 17:55
这篇博文的前两节(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-8byte[] utf8 = str.getBytes("UTF8");// Encryptbyte[] enc = this.eCipher.doFinal(utf8);// Encode bytes to hex stringreturn 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);// Decryptbyte[] utf8 = this.dCipher.doFinal(dec);// Decode using utf-8return new String(utf8, "UTF8");} catch (Exception e) {throw new CryptoException("decrypt failed.", e);}}public byte[] encrypt(byte[] message) throws CryptoException {try {// Encryptreturn 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 {// Decryptedbyte[] decrypted = this.dCipher.doFinal(message);return decrypted;} catch (Exception e) {throw new CryptoException("decrypt failed.", e);}}}
几个工具类的代码我就不贴了。
- java-在非安全网络上建立可信任安全的通道(3/3)
- [置顶] java-在非安全网络上建立可信任安全的通道(1/3)
- [置顶] java-在非安全网络上建立可信任安全的通道(2/3)
- 安全的网络通道
- 如何建立安全通道
- SSL/TLS安全通道建立的WebService 调用
- 未能为 SSL/TLS 安全通道建立信任的解决办法
- JAVA打开安全通道详解
- Java之HashMap在非线程安全时的行为
- 建立安全的AXIS服务(上)
- IPC$共享通道的安全
- JAVA网络程序的安全
- JAVA的线程安全和非线程安全的区别
- 调用Https WebService发布后使用时报“基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系”证书验证失败的解决过程(3)
- Java 非线程安全
- 从NDK在非Root手机上的调试原理探讨Android的安全机制
- 从NDK在非Root手机上的调试原理探讨Android的安全机制
- 从NDK在非Root手机上的调试原理探讨Android的安全机制
- mysql4中出现的本地计算机 无法启动mysql服务 错误1067解决办法
- 泛型类里面获取到泛型的类型
- opensuse 上面运行eclipse崩溃的问题
- asp.net 2.0中的gridview里用crosspage的功能
- linux document viewer 中文乱码、方块
- java-在非安全网络上建立可信任安全的通道(3/3)
- WIN7下面 ARP攻击的检测与处理/静态ARP设置
- asp.net 2.0小tips:在web.config里设置用户定义控件
- Future机制用于并发编程时的死锁检测
- Oracle触发器给表自身的字段重新赋值出现ORA-04091异常
- Java包装类Integer比较
- 数据挖掘中的中位数
- 聚类算法之CHAMELEON(Java实现)
- Linux 下VIM去掉在windows下编辑的文本文件里面回车符号