JDK生成SSL认证文件及加密解析方法

来源:互联网 发布:遗传算法python实现 编辑:程序博客网 时间:2024/06/08 05:51

PS:第一次这么投入的搞个东西搞到这么晚

记录一下:

背景:因为工作中涉及到这样的一个场景,A方希望调用B方的页面,并且传递一些参数过来,如果直接在url后面添加的话,显得不安全,因此希望通过一个加密协议来进行互相认证,于是提到了RSA非对称加密及证书认证


我大改理解思路: 首先是A生成一个公钥和私钥,自己保留私钥,将公钥给对方系统B,而证书里面正是这个公钥

不知道对不对  。。。。 


然后我查了下资料,最简单的生成这样的一对公钥和私钥的方法,使用JDK生成SSL证书

步骤:

CMD 进入jdk目录
1.使用keytool命令生成证书:


输入命令 :
keytool -genkey -alias test -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore E:/dongjinlong/笔记/test.keystore -storepass 123456

填写内容:这个貌似没啥要求


参数解析:



keytool  bin下的keytool.exe


-genkey 


-alias test(别名) 


-keypass 123456(别名密码) 


-keyalg RSA(算法) 


-keysize 1024(密钥长度) 


-validity 365(有效期,天单位) 


-keystore E:/dongjinlong/笔记/test.keystore(指定生成证书的位置和证书名称) 


-storepass 123456(获取keystore信息的密码)

2.在目录下可以找到test.keystore 文件
cmd中输入 keytool -list -v -keystore E:/dongjinlong/笔记/test.keystore -storepass 123456  可以查看

3.由keystore 生成一个证书cer文件

keytool -keystore E:/dongjinlong/笔记/test.keystore -export -alias test -file  E:/dongjinlong/笔记/server.cer


重点:怎么在java代码中使用这两个文件进行加密解密呢

1. 将生成的文件放入到config目录下

2.引入commons-codec-1.10.jar 包



3.测试代码

package 加密证书;


import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;


import org.apache.commons.codec.binary.Base64;
/**
 * 1.先使用CMD 命令使用jdk 的keytool 生成 .keystore文件
 * 2.再由.keystore 文件生成对应的.cer文件
 * 3.将这两个文件导入的config目录下
 * @author 瓜宝
 *
 */
public class Cer {
/**
*  私钥加密的数据与证书解密的数据对比

* @param requestParam 签名的数据 
* 格式String requestParam = "name1=value1&name2=value2&name3=value3";

* @param signParam已签名的数据
* @param cer 证书名称
* @return
*/
public static boolean verifyRSAMessageByPublic(String requestParam, String signParam, String cer) {
if (requestParam == null)
return false;
PublicKey pk = null;
InputStream in = null;
try {
/* 得到X.509证书的工厂类 */
CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509");
/* 加载源文件夹下的.cer证书 参数 cer 为文件名称 server.cer */
in = Thread.currentThread().getContextClassLoader().getResourceAsStream(cer);
X509Certificate Cert = (X509Certificate) certificatefactory.generateCertificate(in);
pk = Cert.getPublicKey();
in.close();
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}


boolean bln = false;
try {
/*RSA解密*/
Signature dsa = Signature.getInstance("SHA1withRSA");
dsa.initVerify(pk);
dsa.update(requestParam.getBytes());
Base64 base64Decoder = new Base64();
//替换回不能通过GET方式传递的字符
signParam = replaceFromUrl(signParam);
bln = dsa.verify(base64Decoder.decode(signParam.getBytes()));
} catch (Exception e) {
e.printStackTrace();
}
return bln;
}
/**
* 测试的main方法
* @param args
*/
public static void main(String[] args) {


// 加密数据
Map<String, String> map = new HashMap<String, String>();
map.put("clientNo", "000938873761");
map.put("type", "XT");
map.put("url", "/res/index.html?_viewType=2&#orderManager/index/membership");
map.put("timestamp", "2017-09-01 13:50:16");
map.put("signdata",
"aSk4FOLpEzZdHEQaL5Se7MH%2F6MMWI5Dv2APU6LuexWgZJMpFTbLpYYpBTahGTq3ZB1RNvDEQ1mlCjYC%2F0yvfVgls3ElXyL44aQdiPKKscpQdn%2FUbBDJbVMaWllekmoTvldzscV%2BNrD3wi9IAao2NnDp9K%2BzOWGHHYVjcPlSCvnw%3D");

StringBuffer sb = new StringBuffer();
sb.append("clientNo=").append(map.get("clientNo"));
sb.append("&type=").append(map.get("type")).append("&timestamp=").append(map.get("timestamp"));
System.out.println("加密前的数据:"+sb.toString());
// 本地能配对的keystore 和 cer 文件
String  keystore = "test.keystore";
String password ="123456";
String alias = "test";
String sig = signData(sb.toString(),keystore,password,alias);
System.out.println(sig);
map.put("signdata", sig);
String cer = "server.cer";
boolean bln = verifyRSAMessageByPublic(sb.toString(), map.get("signdata"), cer);
System.out.println(bln);


}


/**
* 用私钥签名数据
* @param signparam 加密的参数
* 格式String requestParam = "name1=value1&name2=value2&name3=value3";

* @param keystore  源文件夹下私钥.keystore文件的文件名
* @param passwordjdk的keytool 工具生成文件时候设置的密码
* @param aliasjdk的keytool 工具生成文件时候设置的别名
* @return
*/
public static String signData(String signparam, String keystore,String password,String alias) {
InputStream in = null;
try {
KeyStore ks = KeyStore.getInstance("JKS");
in = Thread.currentThread().getContextClassLoader().getResourceAsStream(keystore);
/* jdk的keytool 工具生成文件时候设置的密码 */
char[] storePwd = password.toCharArray();


ks.load(in, storePwd);
in.close();
// jdk的keytool 工具生成文件时候设置的别名
PrivateKey privateKey = (PrivateKey) ks.getKey(alias, storePwd);
Signature dsa = Signature.getInstance("SHA1withRSA");
dsa.initSign(privateKey);
dsa.update(signparam.getBytes());


Base64 base64Encoder = new Base64();
String signDate = new String(base64Encoder.encode(dsa.sign()));
return replaceNoneUrl(signDate);
} catch (Exception gse) {
System.out.println(gse);
return null;
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


/**
* 替换回不能通过GET方式传递的字符

* @return
*/
public static String replaceFromUrl(String str) {
str = str.replaceAll("%2B", "\\+");
str = str.replaceAll("%2F", "\\/");
return str.replaceAll("%3D", "\\=");
}


/**
* 替换不能通过GET方式传递的字符

* @return
*/
public static String replaceNoneUrl(String str) {
str = str.replaceAll("\\+", "%2B");
str = str.replaceAll("\\/", "%2F");
return str.replaceAll("\\=", "%3D");
}


}

输出日志:
加密前的数据:clientNo=000938873761&type=XT&timestamp=2017-09-01 13:50:16
X7yy1TegOvUYgAfK5a7e4e0b8FFNx4BXUYZZoQkxssfgURf%2FrU%2FEmS0GKnbZUeoo%2BYV5rTOhmlBhLSC%2BinLcyQCVRlEcXYEYeZ%2BmCgwcaL0PR1BSa5Ritr%2BvU92l4zXYbk2a9OHM2Y0Ge19gKPQBtatBbmiqrboacaKmz4YeJWY%3D
true


原创粉丝点击