⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commonutil.java

📁 网上找的很稀有的单点登陆资料,基于对称加密算法的.
💻 JAVA
字号:
package com.yayisoft.sso.util;

import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 * TODO XXX 这些类要声明Exception异常,否则将会暴露加密算法的细节!!!!!!
 * 
 * @author mead
 * 
 */
public final class CommonUtil {
	public static String getGuid() {
		return java.util.UUID.randomUUID().toString();
	}

	public static String getStripsByApply(String apply) throws SSOException {		
		return CommonUtil.getDigest(apply);
	}

	public static String getTipsByTokon(String tokon) throws SSOException {
		return CommonUtil.getDigest(tokon);
	}

	public static String getStripsByIntro(String intro) throws SSOException {
		return CommonUtil.getDigest(intro);
	}

	public static boolean checkApply(String apply, String strips)
			throws SSOException {		
		return CommonUtil.checkDigest(apply, strips);
	}

	public static boolean checkTips(String tokon, String tips)
			throws SSOException {		
		return CommonUtil.checkDigest(tokon, tips);
	}

	public static boolean checkIntro(String intro, String strips)
			throws SSOException {
		return CommonUtil.checkDigest(intro, strips);
	}

	/**
	 * 加密用户名,使用apply与intro
	 * apply与intro全是随机的,这意味着无法重放apply攻击Validate来获取userName的规律
	 * 用apply来加密用户名,意味着,无法重放intro,tokon,strips来攻击Anchor()
	 * 
	 * @param userName
	 * @param apply
	 *            申请书
	 * @param intro
	 *            介绍信
	 * @return
	 */
	public static String EncryptUser(String userName, String apply, String intro)
			throws SSOException {
		byte[] salt = CommonUtil.getSalt(intro, apply);		
		return CommonUtil.coding(userName, salt, Mode.ENCRYPT);
	}

	/**
	 * 解密用户名
	 * 
	 * @param userName
	 * @param apply
	 * @param intro
	 * @return
	 */
	public static String DecryptUser(String userName, String apply, String intro)
			throws SSOException {
		byte[] salt = CommonUtil.getSalt(intro, apply);
		return CommonUtil.coding(userName, salt, Mode.DECRYPT);
	}

	private static boolean checkDigest(String info, String digest)
			throws SSOException {
		try {

			MessageDigest alga = java.security.MessageDigest
					.getInstance("SHA-1");
			String text = info + Config.DIGEST_STEING;
			alga.update(text.getBytes("UTF8"));
			byte[] result = alga.digest();
			String digString = CommonUtil.byte2string(result);
			if (digString.equals(digest)) {
				return true;
			} else {
				return false;
			}
		} catch (Exception ex) {
			System.out.println("非法摘要算法");
			SSOException ssoEx = new SSOException("摘要有错误");
			throw ssoEx;
		}
	}
	
	private static String getDigest(String info) throws SSOException {
		try {

			MessageDigest alga = java.security.MessageDigest
					.getInstance("SHA-1");
			String text = info + Config.DIGEST_STEING;
			alga.update(text.getBytes("UTF8"));
			byte[] result = alga.digest();
			System.out.println("####输入明文****"+info+"%%%%%%%%%%%%%%");
			System.out.println("getDigest获取签名...");
			CommonUtil.out(result);
			return CommonUtil.byte2string(result);
		} catch (Exception ex) {
			System.out.println("非法摘要算法");
			SSOException ssoEx = new SSOException("摘要有错误");
			throw ssoEx;
		}
	}
	
	/**
	 * 取盐的方法:
	 * 从apply和intro中获得,两个都不能缺少!!!
	 * @param info
	 * @return
	 * @throws SSOException
	 */
	private static byte[] getSalt(String apply,String intro) throws SSOException {
		try {
			String info = apply +Config.SALT_STEING + intro;//Config.SALT_STEING;附加字符
			MessageDigest alga = java.security.MessageDigest
					.getInstance("SHA-1");
			System.out.println(info+"成盐因子是"+info);
			alga.update(info.getBytes("UTF8"));
			
			byte[] result = alga.digest();			
			byte[] ok = new byte[8];			
			int j = 2;//获取方法
			for(int i=0;i<8;i++){
				ok[i] = result[j];	
				j+=2;				
			}			
			return ok;
		} catch (Exception ex) {
			System.out.println("getDigestInByteArray非法摘要算法");
			SSOException ssoEx = new SSOException("getDigestInByteArray摘要有错误");
			throw ssoEx;
		}
	}
	

	private enum Mode {ENCRYPT, DECRYPT}; 

	

	private static String coding(String text, byte[] salt,Mode m)throws SSOException {
		try {
			for(byte i : salt){
				System.out.println("coding.验证salt.i提前盐粒子="+i);
			}
			char[] pswd = Config.PSWD_STRING.toCharArray();
			PBEKeySpec pbks = new PBEKeySpec(pswd);
			SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
			SecretKey k = kf.generateSecret(pbks);		
			Cipher cp = Cipher.getInstance("PBEWithMD5AndDES");
			PBEParameterSpec ps = new PBEParameterSpec(salt, 1000);
			byte[] result;
			if(m==Mode.ENCRYPT){				
				cp.init(Cipher.ENCRYPT_MODE, k, ps);
				result = cp.doFinal(text.getBytes());
			}else{
				cp.init(Cipher.DECRYPT_MODE, k, ps);
				result = cp.doFinal(CommonUtil.hex2byte(text.getBytes()));//解密模式,将密文(HEX)转换为byte[],进行操作
			}			
			

			// //将盐和加密结果放在一起,作为密文
			// FileOutputStream f = new FileOutputStream("PBEEnc.dat");
			// f.write(salt);
			// f.write(ctext);
			// f.close();
			System.out.print("coding的盐是:");
			CommonUtil.out(salt);
			System.out.print("result的结果是:");
			CommonUtil.out(result);
			
			System.out.println("####################原文是:" + new String(text));
			System.out.println("####################密文是:"	+ new String(result));
			if(m==Mode.ENCRYPT){//如果是加密,将byte[]转换为HEX,便于传输!!!
				return CommonUtil.byte2hex(result);
			}else{
				return new String(result);
			}			
		} catch (Exception e) {
			System.out.println("getDigestInByteArray非法摘要算法"+e.getMessage());
			SSOException ssoEx = new SSOException("getDigestInByteArray摘要有错误");
			//e.printStackTrace();
			throw ssoEx;
		}

	}

	/**
	 * 拼接方式!!!非转换
	 * @param b
	 * @return
	 */
	private static String byte2string(byte[] b){
		StringBuffer sb = new StringBuffer();
		for(byte i : b){
			sb.append(i);
			System.out.print(i);
		}
		return sb.toString();
	}
	/** 
     * java字节码转字符串 
     * @param b 
     * @return 
     */
    private static String byte2hex(byte[] b) { //一个字节的数,

        // 转成16进制字符串

        String hs = "";
        String tmp = "";
        for (int n = 0; n < b.length; n++) {
            //整数转成十六进制表示

            tmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (tmp.length() == 1) {
                hs = hs + "0" + tmp;
            } else {
                hs = hs + tmp;
            }
        }
        tmp = null;
        return hs.toUpperCase(); //转成大写

    }

    /**
     * 字符串转java字节码
     * @param b
     * @return
     */
    private static byte[] hex2byte(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);
            // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个进制字节
            b2[n / 2] = (byte) Integer.parseInt(item, 16);
        }
        b = null;
        return b2;
    }

	
	private static void out(byte[] b) {
		System.out.println("开始输出消息摘要:\n\n");
		for (byte i : b) {
			System.out.print(i);
		}
		System.out.println("\n开消息摘要结束");
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -