zoukankan      html  css  js  c++  java
  • 【Android工具类】怎样保证Android与server的DES加密保持一致

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

        在我们的应用程序涉及到比較敏感的数据的时候,我们一般会对数据进行简单的加密。在与server之间的数据交互中,除了能够使用post请求来增强数据的安全性之外。我们能够使用常见的加密算法。对数据进行加密。

    今天主要介绍的是DES加密算法。

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

        

        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模式指的是电子password本模式,是一种最古老,最简单的模式。将加密的数据分成若干组,每组的大小跟加密密钥长度同样;然后每组都用同样的密钥加密, 比方DES算法, 假设最后一个分组长度不够64位,要补齐64位。

    这样的模式的特点是:

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

        2.数据块反复排序不须要检測;

        3.同样的明文块(使用同样的密钥)产生同样的密文块。easy遭受字典攻击;

        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.採用同样的填充模式

       

  • 相关阅读:
    HDU 1002 A + B Problem II
    HDU 2602 Bone Collector WA谁来帮忙找找错
    爬楼梯问题-最大迈两步
    2106 Problem F Shuffling Along 中石油-未提交-->已提交
    2101 Problem A Snake Filled
    2078 Problem H Secret Message 中石油-未提交-->已提交
    有关 时间 空间 以及 数据类型 的总结
    hdu 2510
    hdu 1133 卡特兰 高精度
    hdu 2067
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7251841.html
Copyright © 2011-2022 走看看