DES 对称加密 适用于 android 和 web

本文详细介绍了如何在Android和Web端使用DES算法实现密保信息的安全存储与读取,通过封装类简化了加密和解密过程,并确保了数据的一致性。实现了密保数据在不同平台间的双向验证。

最近开发android项目原本在写一个密保保存功能的时候用到了DES,先用户登录成功的密码DES加密用XML形式存储起来(如果项目大可以把sqlite加密直接放在数据库里).然后在用户加载登录界面时自动读取XML加密后的文本在用DES解码。

开始的时候是在网上直接copy的一个封装类用,

但是后来功能的扩展需要满足android 于 web服务器端的双向验证.于是吧android 用的DES封装类copy在 web端 2者加密后得到的密文是不一样的.

所以又找了一种别人写好的DES 算法,可以满足web端和 android 机密形成的方式一样

下面代码:

package com.hnjh.jswy.utils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;

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

/**
 * DES对称封装类
 * 
 * @author xuguang
 * 
 */
public class DESUtil {
	/** 加密、解密key. */
	private static final String PASSWORD_CRYPT_KEY = AppConstant.PASSWORD_CRYPT_KEY;

	private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
	private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

	.toCharArray();

	/**
	 * 对用DES加密过的数据进行解密.
	 * 
	 * @param data
	 *            DES加密数据
	 * @return 返回解密后的数据
	 * @throws Exception
	 * @author xuguang
	 */
	public final static String decrypt(String data) throws Exception {
		return decryptDES(data, PASSWORD_CRYPT_KEY);
	}

	/**
	 * 对数据进行DES加密.
	 * 
	 * @param data
	 *            待进行DES加密的数据
	 * @return 返回经过DES加密后的数据
	 * @throws Exception
	 * @author xuguang
	 */
	public final static String encrypt(String data) throws Exception {
		return encryptDES(data, PASSWORD_CRYPT_KEY);
	}

	private static String encryptDES(String encryptString, String encryptKey)

	throws Exception {

		IvParameterSpec zeroIv = new IvParameterSpec(iv);

		SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");

		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

		cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);

		byte[] encryptedData = cipher.doFinal(encryptString.getBytes());

		return encode(encryptedData);

	}

	private static String encode(byte[] data) {

		int start = 0;

		int len = data.length;

		StringBuffer buf = new StringBuffer(data.length * 3 / 2);

		int end = len - 3;

		int i = start;

		int n = 0;

		while (i <= end) {

			int d = ((((int) data[i]) & 0x0ff) << 16)

			| ((((int) data[i + 1]) & 0x0ff) << 8)

			| (((int) data[i + 2]) & 0x0ff);

			buf.append(legalChars[(d >> 18) & 63]);

			buf.append(legalChars[(d >> 12) & 63]);

			buf.append(legalChars[(d >> 6) & 63]);

			buf.append(legalChars[d & 63]);

			i += 3;

			if (n++ >= 14) {

				n = 0;

				buf.append(" ");

			}

		}

		if (i == start + len - 2) {

			int d = ((((int) data[i]) & 0x0ff) << 16)

			| ((((int) data[i + 1]) & 255) << 8);

			buf.append(legalChars[(d >> 18) & 63]);

			buf.append(legalChars[(d >> 12) & 63]);

			buf.append(legalChars[(d >> 6) & 63]);

			buf.append("=");

		} else if (i == start + len - 1) {

			int d = (((int) data[i]) & 0x0ff) << 16;

			buf.append(legalChars[(d >> 18) & 63]);

			buf.append(legalChars[(d >> 12) & 63]);

			buf.append("==");

		}

		return buf.toString();

	}

	/**
	 * 解密
	 * 
	 * @param data
	 *            待解密字符串
	 * @param key
	 *            解密私钥,长度不能够小于8位
	 * @return 解密后的字节数组
	 * @throws Exception
	 *             异常
	 */

	private static String decryptDES(String decryptString, String decryptKey)

	throws Exception {

		byte[] byteMi = decode(decryptString);

		IvParameterSpec zeroIv = new IvParameterSpec(iv);

		SecretKeySpec key = new SecretKeySpec(decryptKey.getBytes(), "DES");

		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

		cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);

		byte decryptedData[] = cipher.doFinal(byteMi);

		return new String(decryptedData);

	}

	private static byte[] decode(String s) {

		ByteArrayOutputStream bos = new ByteArrayOutputStream();

		try {

			decode(s, bos);

		} catch (IOException e) {

			throw new RuntimeException();

		}

		byte[] decodedBytes = bos.toByteArray();

		try {

			bos.close();

			bos = null;

		} catch (IOException ex) {

			System.err.println("Error while decoding BASE64: " + ex.toString());

		}

		return decodedBytes;

	}

	private static void decode(String s, OutputStream os) throws IOException {

		int i = 0;

		int len = s.length();

		while (true) {

			while (i < len && s.charAt(i) <= ' ')

				i++;

			if (i == len)

				break;

			int tri = (decode(s.charAt(i)) << 18)

			+ (decode(s.charAt(i + 1)) << 12)

			+ (decode(s.charAt(i + 2)) << 6)

			+ (decode(s.charAt(i + 3)));

			os.write((tri >> 16) & 255);

			if (s.charAt(i + 2) == '=')

				break;

			os.write((tri >> 8) & 255);

			if (s.charAt(i + 3) == '=')

				break;

			os.write(tri & 255);

			i += 4;

		}

	}

	private static int decode(char c) {

		if (c >= 'A' && c <= 'Z')

			return ((int) c) - 65;

		else if (c >= 'a' && c <= 'z')

			return ((int) c) - 97 + 26;

		else if (c >= '0' && c <= '9')

			return ((int) c) - 48 + 26 + 26;

		else

			switch (c) {

			case '+':

				return 62;

			case '/':

				return 63;

			case '=':

				return 0;

			default:

				throw new RuntimeException("unexpected code: " + c);

			}

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值