/** * */ package com.mtools.core.plugin.security; import java.io.FileInputStream; import java.security.KeyStore; import java.security.Provider; import java.security.Signature; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.RSAPrivateCrtKey; import java.security.interfaces.RSAPublicKey; import java.util.Enumeration; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * @author Administrator * */ public class CryptNoRestrict implements CryptInf { public static Provider provider = new BouncyCastleProvider(); /** * 构造函数 */ public CryptNoRestrict() { } public CryptNoRestrict(String encoding) { this.encoding=encoding; } private String encoding = "GBK"; /** * 取出上次调用加密、解密、签名函数成功后的输出结果 */ protected String lastResult; /** * 返回上一次签名结果 */ protected String lastSignMsg; /** * 对字符串进行签名 * * @param TobeSigned * 需要进行签名的字符串 * @param KeyFile * PFX证书文件路径 * @param PassWord * 私钥保护密码 * @return 签名成功返回true(从LastResult属性获取结果),失败返回false(从LastErrMsg属性获取失败原因) */ public boolean SignMsg(final String TobeSigned, final String KeyFile, final String PassWord) throws Exception { boolean result = false; FileInputStream fiKeyFile = null; this.lastSignMsg = ""; KeyStore ks = KeyStore.getInstance("PKCS12"); // ks.load(new FileInputStream(KeyFile), PassWord.toCharArray()); fiKeyFile = new FileInputStream(KeyFile); //PassWord.toCharArray() try { ks.load(fiKeyFile,PassWord.toCharArray()); } catch(Exception ex) { if(fiKeyFile!=null) fiKeyFile.close(); throw ex; } Enumeration myEnum = ks.aliases(); String keyAlias = null; RSAPrivateCrtKey prikey = null; // keyAlias = (String) myEnum.nextElement(); /* IBM JDK必须使用While循环取最后一个别名,才能得到个人私钥别名 */ while (myEnum.hasMoreElements()) { keyAlias = (String) myEnum.nextElement(); // System.out.println("keyAlias==" + keyAlias); if (ks.isKeyEntry(keyAlias)) { prikey = (RSAPrivateCrtKey) ks.getKey(keyAlias, PassWord.toCharArray()); break; } } if (prikey == null) { result = false; throw new Exception("没有找到匹配私钥"); } else { Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(prikey); sign.update(TobeSigned.getBytes(encoding)); byte signed[] = sign.sign(); byte sign_asc[] = new byte[signed.length * 2]; Hex2Ascii(signed.length, signed, sign_asc); this.lastResult = new String(sign_asc); this.lastSignMsg = this.lastResult; result = true; } return result; } /** * 验证签名 * * @param TobeVerified * 待验证签名的密文 * @param PlainText * 待验证签名的明文 * @param CertFile * 签名者公钥证书 * @return 验证成功返回true,失败返回false(从LastErrMsg属性获取失败原因) */ public boolean VerifyMsg(String TobeVerified, String PlainText, String CertFile) throws Exception { boolean result = false; FileInputStream certfile = null; certfile = new FileInputStream(CertFile); CertificateFactory cf = CertificateFactory.getInstance("X.509"); X509Certificate x509cert=null; try { x509cert = (X509Certificate) cf.generateCertificate(certfile); } catch(Exception ex) { if(certfile!=null) certfile.close(); throw ex; } RSAPublicKey pubkey = (RSAPublicKey) x509cert.getPublicKey(); Signature verify = Signature.getInstance("SHA1withRSA"); verify.initVerify(pubkey); byte signeddata[] = new byte[TobeVerified.length() / 2]; Ascii2Hex(TobeVerified.length(), TobeVerified.getBytes(encoding), signeddata); verify.update(PlainText.getBytes(encoding)); if (verify.verify(signeddata)) { result = true; } else { result = false; throw new Exception("验签失败"); } return result; } /** * 返回上次调用加密、解密、签名函数成功后的输出结果 * * @return 返回上次调用加密、解密、签名函数成功后的输出结果 */ public String getLastResult() { return this.lastResult; } /** * 返回上一次签名结果 * * @return 签名结果 */ public String getLastSignMsg() { return this.lastSignMsg; } /** * 将十六进制数据转换成ASCII字符串 * * @param len * 十六进制数据长度 * @param data_in * 待转换的十六进制数据 * @param data_out * 已转换的ASCII字符串 */ private static void Hex2Ascii(int len, byte data_in[], byte data_out[]) { byte temp1[] = new byte[1]; byte temp2[] = new byte[1]; for (int i = 0, j = 0; i < len; i++) { temp1[0] = data_in[i]; temp1[0] = (byte) (temp1[0] >>> 4); temp1[0] = (byte) (temp1[0] & 0x0f); temp2[0] = data_in[i]; temp2[0] = (byte) (temp2[0] & 0x0f); if (temp1[0] >= 0x00 && temp1[0] <= 0x09) { (data_out[j]) = (byte) (temp1[0] + '0'); } else if (temp1[0] >= 0x0a && temp1[0] <= 0x0f) { (data_out[j]) = (byte) (temp1[0] + 0x57); } if (temp2[0] >= 0x00 && temp2[0] <= 0x09) { (data_out[j + 1]) = (byte) (temp2[0] + '0'); } else if (temp2[0] >= 0x0a && temp2[0] <= 0x0f) { (data_out[j + 1]) = (byte) (temp2[0] + 0x57); } j += 2; } } /** * 将ASCII字符串转换成十六进制数据 * * @param len * ASCII字符串长度 * @param data_in * 待转换的ASCII字符串 * @param data_out * 已转换的十六进制数据 */ private static void Ascii2Hex(int len, byte data_in[], byte data_out[]) { byte temp1[] = new byte[1]; byte temp2[] = new byte[1]; for (int i = 0, j = 0; i < len; j++) { temp1[0] = data_in[i]; temp2[0] = data_in[i + 1]; if (temp1[0] >= '0' && temp1[0] <= '9') { temp1[0] -= '0'; temp1[0] = (byte) (temp1[0] << 4); temp1[0] = (byte) (temp1[0] & 0xf0); } else if (temp1[0] >= 'a' && temp1[0] <= 'f') { temp1[0] -= 0x57; temp1[0] = (byte) (temp1[0] << 4); temp1[0] = (byte) (temp1[0] & 0xf0); } if (temp2[0] >= '0' && temp2[0] <= '9') { temp2[0] -= '0'; temp2[0] = (byte) (temp2[0] & 0x0f); } else if (temp2[0] >= 'a' && temp2[0] <= 'f') { temp2[0] -= 0x57; temp2[0] = (byte) (temp2[0] & 0x0f); } data_out[j] = (byte) (temp1[0] | temp2[0]); i += 2; } } protected String replaceAll(String strURL, String strAugs) { // JDK1.3中String类没有replaceAll的方法 /** ********************************************************** */ int start = 0; int end = 0; String temp = new String(); while (start < strURL.length()) { end = strURL.indexOf(" ", start); if (end != -1) { temp = temp.concat(strURL.substring(start, end).concat("%20")); if ((start = end + 1) >= strURL.length()) { strURL = temp; break; } } else if (end == -1) { if (start == 0) break; if (start < strURL.length()) { temp = temp.concat(strURL.substring(start, strURL.length())); strURL = temp; break; } } } temp = ""; start = end = 0; while (start < strAugs.length()) { end = strAugs.indexOf(" ", start); if (end != -1) { temp = temp.concat(strAugs.substring(start, end).concat("%20")); if ((start = end + 1) >= strAugs.length()) { strAugs = temp; break; } } else if (end == -1) { if (start == 0) break; if (start < strAugs.length()) { temp = temp.concat(strAugs.substring(start, strAugs.length())); strAugs = temp; break; } } } /** **************************************************************** */ return strAugs; } }