【Android开发经验】如何保证Android与服务器的DES加密保持一致

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992

在我们的应用程序涉及到比较敏感的数据的时候,我们通常会对数据进行简单的加密。在与服务器之间的数据交互中,除了可以使用post请求来增强数据的安全性之外,我们可以使用常见的加密算法,对数据进行加密。今天主要介绍的是DES加密算法。

首先,DES属于一种对称的加密算法,所谓对称,就是说加密和解密使用的都是同一个密钥,那么在我们实际应用的时候,就是指服务器和客户端进行加密解密的时候,使用的是一个相同的密钥。除此之外,还有非对称加密算法,就是公钥私钥机制,这种方式可以被用来进行身份验证,这个以后再细说。

DES全称为Data EncryptionStandard,即数据加密标准,是一种使用密钥加密的块算法,DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。

下面是在Java或者是Android里面,进行DES加密的代码实现

package com.qust.rollcallstudent.utils;

import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Locale;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

/**
 *
 * @ClassName: com.qust.rollcallstudent.utils.DESUtil
 * @Description: DES加密解密工具包
 * @author zhaokaiqiang
 * @date 2014-11-13 下午8:40:56
 *
 */
public class DESUtil {

	public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding";

	/**
	 * DES算法,加密
	 *
	 * @param data
	 *            待加密字符串
	 * @param key
	 *            加密私钥,长度不能够小于8位
	 * @return 加密后的字节数组,一般结合Base64编码使用
	 * @throws InvalidAlgorithmParameterException
	 * @throws Exception
	 */
	public static String encode(String key, String data) {
		if (data == null)
			return null;
		try {
			DESKeySpec dks = new DESKeySpec(key.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			// key的长度不能够小于8位字节
			Key secretKey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
			IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
			AlgorithmParameterSpec paramSpec = iv;
			cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
			byte[] bytes = cipher.doFinal(data.getBytes());
			return byte2String(bytes);
		} catch (Exception e) {
			e.printStackTrace();
			return data;
		}
	}

	/**
	 * DES算法,解密
	 *
	 * @param data
	 *            待解密字符串
	 * @param key
	 *            解密私钥,长度不能够小于8位
	 * @return 解密后的字节数组
	 * @throws Exception
	 *             异常
	 */
	public static String decode(String key, String data) {
		if (data == null)
			return null;
		try {
			DESKeySpec dks = new DESKeySpec(key.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			// key的长度不能够小于8位字节
			Key secretKey = keyFactory.generateSecret(dks);
			Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
			IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
			AlgorithmParameterSpec paramSpec = iv;
			cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
			return new String(cipher.doFinal(byte2hex(data.getBytes())));
		} catch (Exception e) {
			e.printStackTrace();
			return data;
		}
	}

	/**
	 * 二行制转字符串
	 *
	 * @param b
	 * @return
	 */
	private static String byte2String(byte[] b) {
		StringBuilder hs = new StringBuilder();
		String stmp;
		for (int n = 0; b != null && n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append('0');
			hs.append(stmp);
		}
		return hs.toString().toUpperCase(Locale.CHINA);
	}

	/**
	 * 二进制转化成16进制
	 *
	 * @param b
	 * @return
	 */
	private static byte[] byte2hex(byte[] b) {
		if ((b.length % 2) != 0)
			throw new IllegalArgumentException();
		byte[] b2 = new byte[b.length / 2];
		for (int n = 0; n < b.length; n += 2) {
			String item = new String(b, n, 2);
			b2[n / 2] = (byte) Integer.parseInt(item, 16);
		}
		return b2;
	}

}

如果大家只是想用,就可以不用往下看了,下面开始说一些关于DES算法的细节。

在上面的加密和解密的方法里面,我们在获取Cipher实例的时候,传入了一个字符串"DES/CBC/PKCS5Padding",这三个参数是什么意思呢?

实际上,这三个参数分别对应的是“算法/模式/填充”,也就是说我们要用DES算法进行加密,采用的是CBC模式,填充方式采用PKCS5Padding。

除了CBC模式,还有ECB模式等,指的是不同的加密方式。

那么CBC模式和ECB模式又有什么区别呢?

ECB模式指的是电子密码本模式,是一种最古老,最简单的模式,将加密的数据分成若干组,每组的大小跟加密密钥长度相同;然后每组都用相同的密钥加密, 比如DES算法, 如果最后一个分组长度不够64位,要补齐64位。这种模式的特点是:

1.每次Key、明文、密文的长度都必须是64位;

2.数据块重复排序不需要检测;

3.相同的明文块(使用相同的密钥)产生相同的密文块,容易遭受字典攻击;

4.一个错误仅仅会对一个密文块产生影响;

CBC模式指的是加密块链模式,与ECB模式最大的不同是加入了初始向量。下面的代码就是获取一个初始向量,

IvParameterSpec iv =
new IvParameterSpec("12345678".getBytes());

这种模式的特点是:

1.每次加密的密文长度为64位(8个字节);

2.当相同的明文使用相同的密钥和初始向量的时候CBC模式总是产生相同的密文;

3.密文块要依赖以前的操作结果,所以,密文块不能进行重新排列;

4.可以使用不同的初始化向量来避免相同的明文产生相同的密文,一定程度上抵抗字典攻击;

5.一个错误发生以后,当前和以后的密文都会被影响;

PKCS5Padding参数则是在说明当数据位数不足的时候要采用的数据补齐方式,也可以叫做数据填充方式。

PKCS5Padding这种填充方式,具体来说就是“填充的数字代表所填字节的总数”

比如说,差两个字节,就是######22,差5个字节就是###55555,这样根据最后一个自己就可以知道填充的数字和数量。

介绍完DES的这些细节之后,我们就可以知道,在不同的平台上,只要能保证这几个参数的一致,就可以实现加密和解密的一致性。

1.加密和解密的密钥一致

2.采用CBC模式的时候,要保证初始向量一致

3.采用相同的填充模式

时间: 2024-12-21 05:22:23

【Android开发经验】如何保证Android与服务器的DES加密保持一致的相关文章

关于 Des加密(Android与ios 与后台java服务器之间的加密解密)

关于 Des加密(Android与ios  与后台java服务器之间的加密解密) http://blog.sina.com.cn/s/blog_7c8dc2d50101id91.html (2013-04-17 11:47:23)   分类: iPhone开发 最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android.iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不

Android开发经验分享(5)Android优化小结

项目中何时不会用到优化呢,现把一些优化的小经验总结下 1.万恶的static static是个好东西,声明赋值调用就是那么的简单方便,但是伴随而来的还有性能问题.由于static声明变量的生命周期其实是和APP的生命周期一样的,有点类似与Application.如果大量的使用的话,就会占据内存空间不释放,积少成多也会造成内存的不断开销,直至挂掉.static的合理使用一般用来修饰基本数据类型或者轻量级对象,尽量避免修复集合或者大对象,常用作修饰全局配置项.工具类方法.内部类. 2.无关引用 很多

【Android开发经验】使用Android Studio进行单元测试

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 Android Studio已经到了1.2版本,国内的开发者基本也在从Eclipse向Android Studio进行转变,对于Android开发者,以后必将是Android Studio的天下. 昨天在完善煎蛋项目的时候,需要进行单元测试,在Eclipse环境中进行是很简单的,但是在Android Studio环境中进行单元测试,我还没有尝试过,在国内找了很多资料,大都是人云亦云,也没有测试成功,然后在

【Android开发经验】我们要友好的告诉用户,程序要崩溃了

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 虽然我们的程序在正式上线之前,都会经过严格的测试,从而保证程序的健壮性和良好的用户体验,但是,一个人的测试或者是几个人的测试团队,都不能和上万甚至数十万的用户相比.因此,前期刚上线的程序在用户手里被玩崩了,也是很常见的事,但是,如果我们不做特殊处理,系统自带的程序崩溃提示真的太吓人了,用户看到之后会不知所措,因此,我们需要一个解决方案,就是在程序即将崩溃的时候,给用户一个更加友好的提示,来告诉他,程序马上

Android开发经验分享-GridView、ListView内容错乱

在使用GridView.ListView的过程中遇到内容错乱的问题,费了较长时间才找到问题的根源,特地总结一下. 1.在自定义adapter中没有给每一项都设置内容导致内容错乱: @Override public View getView(final int position, View convertView, ViewGroup parent) { if( null == convertView ){ mGridHolder = new GridHolder( ); convertView

android 发送UDP广播,搜寻服务器建立socket链接

应用场景:客户端(手机,pc)需要搜寻所在局域网内的服务器并获得服务器地址. 方法简介:客户端发送UDP广播,服务收到广播后得到客户端ip地址,然后向客户端发送一次socket链接,客户端收到socket链接,获得服务器地址. 相关知识: UPD.TCP.TCP是面向链接的,可靠的通信方式.UDP是面向非链接的通讯方式.TCP的建立比较麻烦,要经过"三次握手".而UDP的建立比较简单,发送方只管把内容发送出去,不管接收方是否收到.UDP的传输分为:单播,多播,广播.其中,多播和广播是通

android系统访问自己的tomcat服务器下的项目不能访问的原因

今天做android的一个下载功能,用自己机子上的tomcat做服务器,在tomcat上下载东西,可是android系统老是提示错误说不能连接到我的tomcat,可是我明明启动了tomcat服务啊,而且代码我也检查了好就变了,没有错啊,这可是把我给郁闷坏了,相信很多初学者都会有这样的经历,呵呵...真是不知所措,挺让人郁闷的,我在这里和大家分享一下解决方法,呵呵...找到我这篇文章你就算是找到解决办法了.原因其实很简单,开始我的链接写的是:http://127.0.0.1:8090/项目的名字/

【Android开发经验】DES加密时代的终结者——AES加密算法

转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 在前面的两篇文章中,我们介绍了DES算法,3DES算法以及他们的Android程序实现,并研究了如何才能实现不同平台下加密算法的一致性.不过话说起来,DES算法是在1976年被美国的国家标准局定为联邦资料的加密标准的,到现在已经接近40年了.我们都知道,在计算机的世界里有一个摩尔定律,就是每过18个月,计算机的晶体管的数量就会翻一番,对应的计算速度也会翻倍,虽然现在的发展速度有所放缓,但是每过三年左右,计

Android开发经验—不要指望类的finalize方法干你想要干的活

之所以专门写一篇关于finalize方法的博客,是因为被这个方法坑过,在写一个读取jni数据类的时候,我在类的finalize方法中调用了关闭文件和释放内存的方法,结果导致在频繁调用这个类的时候在JNI里面报异常,类本来就是单例的,按理分析不应该存在这样的情况,到最后分析出来就是因为在该类的finalize方法中调用了关闭文件的方法,导致下次进入再次打开文件时,被系统调用finalize方法给关闭掉了,出现异常的代码如下. public class TraceHandle{ static{ tr